private object scan_once(String str, Regexp pat, ref int start, Frame caller) { Match match; if (pat.rb_reg_search(str, start, false, caller) >= 0) { match = Regexp.rb_backref_get(caller); if (match.value.Length == 0) /* * Always consume at least one character of the input string */ start = match.value.Index + 1; else start = match.value.Index + match.value.Length; if (match.value.Groups.Count == 1) return Regexp.rb_reg_nth_match(0, match); else { Array result = new Array(); for (int i = 1; i < match.value.Groups.Count; i++) result = result.Add(Regexp.rb_reg_nth_match(i, match)); return result; } } else return null; }
internal static int rb_reg_options(Frame caller, Regexp re) //author: war, status: done { int options; rb_reg_check(caller, re); options = OptionsToInt(re.value.Options) & ((int)RE_OPTION.IGNORECASE | (int)RE_OPTION.MULTILINE | (int)RE_OPTION.EXTENDED); return options; }
public override object Call(Class last_class, object recv, Frame caller, Proc block, Array rest) { String str = (String)recv; Class.rb_scan_args(caller, rest, 0, 2, false); object limit = null; int lim = 0; int i = 0; if (rest.Count == 2) { limit = rest[1]; lim = Numeric.rb_num2long(limit, caller); if (lim <= 0) limit = null; else if (lim == 1) { if (str.value.Length == 0) return new Array(); return new Array(str); } i = 1; } bool awk_split = false; object spat = null; if (rest.Count > 0) spat = rest[0]; if (spat == null) { if (String.rb_fs != null && String.rb_fs.value != null) spat = String.rb_fs.value; else awk_split = true; } if (!awk_split) { if (spat is String && ((String)spat).value.Length == 1) { if (((String)spat).value[0] == ' ') awk_split = true; else spat = new Regexp(Regexp.rb_reg_quote((String)spat).value, 0); } else spat = String.get_pat(spat, true, caller); } Array result = new Array(); int beg = 0; if (awk_split) { string[] strings; if (limit != null) strings = str.value.Split(new char[] { ' ' }, lim, System.StringSplitOptions.RemoveEmptyEntries); else strings = str.value.Split(new char[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries); foreach (string s in strings) { String s1 = new String(s); Object.obj_infect(s1, str); result.Add(s1); if (limit != null) i++; } beg = str.value.Length; } else { Regexp pat = (Regexp)spat; int start = beg; int end; bool last_null = false; while ((end = pat.rb_reg_search(str, start, false, caller)) >= 0) { Match regs = Regexp.rb_backref_get(caller); if (start == end && regs.value.Length == 0) { if (str.value.Length == 0) { result.Add(new String()); break; } else if (last_null) { String s = new String(str.value.Substring(beg, 1)); Object.obj_infect(s, str); result.Add(s); beg = start; } else { start += 1; last_null = true; continue; } } else if (start == end && last_null && pat.value.ToString().Equals(regs.value.Value)) { beg = start = regs.value.Index + regs.value.Length; } else { String s = new String(str.value.Substring(beg, end - beg)); Object.obj_infect(s, str); result.Add(s); beg = start = regs.value.Index + regs.value.Length; } last_null = false; for (int idx = 1; idx < regs.value.Groups.Count; idx++) { String tmp; if (regs.value.Groups[idx].Length == 0) tmp = new String(); else tmp = new String(regs.value.Groups[idx].Value); Object.obj_infect(tmp, str); result.Add(tmp); } if (limit != null && lim <= ++i) break; } } if (str.value.Length > 0 && (limit != null || str.value.Length > beg || lim < 0)) { String tmp; if (str.value.Length == beg) tmp = new String(); else tmp = new String(str.value.Substring(beg)); Object.obj_infect(tmp, str); result.Add(tmp); } if (limit == null && lim == 0) while (result.Count > 0 && ((String)result.value[result.Count - 1]).value.Length == 0) result.value.RemoveAt(result.value.Count - 1); return result; }
internal static void rb_reg_raise(Frame caller, string err, Regexp re) { String desc = rb_reg_desc(caller, re); throw new RegExpError(string.Format(CultureInfo.InvariantCulture, "{0}: {1}", err, desc.value)).raise(caller); }
internal static String rb_reg_desc(Frame caller, Regexp re) { System.Text.StringBuilder str = new System.Text.StringBuilder("/"); str.Append(re.pattern); str.Append("/"); if (re != null && re.value != null) { rb_reg_check(caller, re); if (InOptions(re.value.Options, RE_OPTION.MULTILINE)) str.Append("m"); if (InOptions(re.value.Options, RE_OPTION.IGNORECASE)) str.Append("i"); if (InOptions(re.value.Options, RE_OPTION.EXTENDED)) str.Append("x"); } String result = new String(str.ToString()); result.Tainted |= re.Tainted; return result; }
internal static void rb_reg_check(Frame caller, Regexp re) { if (re == null || re.value == null) { throw new TypeError("uninitialized Regexp").raise(caller); } }
internal static void rb_str_subpat_set(String str, Regexp re, int nth, object val, Frame caller) { Match match; int start, len; if (re.rb_reg_search(str, 0, false, caller) < 0) { throw new IndexError("regexp not matched").raise(caller); } match = Regexp.rb_backref_get(caller); if (nth >= match.value.Groups.Count) { throw new IndexError(string.Format(CultureInfo.InvariantCulture, "index {0} out of regexp", nth)).raise(caller); } if (nth < 0) { if (-nth >= match.value.Groups.Count) { throw new IndexError(string.Format(CultureInfo.InvariantCulture, "index {0} out of regexp", nth)).raise(caller); } nth += match.value.Groups.Count; } start = match.value.Groups[nth].Index; if (start == -1) { throw new IndexError(string.Format(CultureInfo.InvariantCulture, "regexp group {0} not matched", nth)).raise(caller); } len = match.value.Groups[nth].Length; rb_str_splice(caller, str, start, len, val); }
internal static String rb_str_subpat(String str, Regexp re, int nth, Frame caller) { if (re.rb_reg_search(str, 0, false, caller) >= 0) { return Regexp.rb_reg_nth_match(nth, Regexp.rb_backref_get(caller)); } return null; }