// -------------------------------------------------------------------------------- internal static Array match_array(Match match, int start) { bool taint = match.Tainted; System.Collections.ArrayList result = new System.Collections.ArrayList(); foreach (System.Text.RegularExpressions.Group group in match.value.Groups) { String str; if (group.Success) { str = new String(group.Value); str.Tainted = taint; } else { str = null; } result.Add(str); } if (start == 0) return new Array(result); return new Array(result.GetRange(start, result.Count - 1)); }
internal static String rb_reg_match_last(Match match) { int i; if (match == null) return null; if (match.value.Groups[0].Index == -1) return null; for (i = match.value.Groups.Count - 1; match.value.Groups[i].Index == -1 && i > 0; i--) ; if (i == 0) return null; return rb_reg_nth_match(i, match); }
internal static String rb_reg_last_match(Match match) { return rb_reg_nth_match(0, match); }
internal static String rb_reg_nth_match(int nth, Match match) { String str; int start; if (match == null) return null; if (nth >= match.value.Groups.Count) { return null; } if (nth < 0) { nth += match.value.Groups.Count; if (nth <= 0) return null; } start = match.value.Groups[nth].Index; if (start == -1 || !match.value.Groups[nth].Success) return null; str = new String(match.value.Groups[nth].Value); str.Tainted |= match.Tainted; return str; }
internal static bool rb_reg_nth_defined(int nth, Match match) { if (match == null) return false; if (nth >= match.value.Groups.Count) { return false; } if (nth < 0) { nth += match.value.Groups.Count; if (nth <= 0) return false; } return (match.value.Groups[nth].Index != -1); }
internal static String rb_reg_regsub(String repl, String src, Match match) { String str = new String(src.value); // Can't use .NET regular expression replacement as semantics are different to Ruby int replsub; if ((replsub = repl.value.IndexOf('\\')) >= 0) { System.Text.StringBuilder replstr = new System.Text.StringBuilder(repl.value.Substring(0, replsub)); for (; replsub < repl.value.Length; replsub++) { if (repl.value[replsub] == '\\' && repl.value.Length > replsub) if (char.IsDigit(repl.value[replsub + 1])) { int i = 2; for (; replsub + i < repl.value.Length; i++) if (!char.IsDigit(repl.value[replsub + i])) break; int matchnum = int.Parse(repl.value.Substring(replsub + 1, i - 1), CultureInfo.InvariantCulture); if (matchnum < match.value.Groups.Count) replstr.Append(match.value.Groups[matchnum]); replsub += i - 1; } else if (repl.value[replsub + 1] == '&') { replstr.Append(src.value); replsub++; } else replstr.Append(repl.value[replsub]); else replstr.Append(repl.value[replsub]); } str.value = str.value.Remove(match.value.Index, match.value.Length); str.value = str.value.Insert(match.value.Index, replstr.ToString()); } else { str.value = str.value.Remove(match.value.Index, match.value.Length); str.value = str.value.Insert(match.value.Index, repl.value); } return str; }
internal int rb_reg_search(String str, int pos, bool reverse, Frame caller) { Regexp re = this; int result; Match match; System.Text.RegularExpressions.Match regs; if (pos > str.value.Length || pos < 0) { rb_backref_set(null, caller); return -1; } rb_reg_check(caller, re); string str_for_match = str.value; // Don't match /^$/ =~ "abc\n" if (re.pattern == "^$" && str_for_match.EndsWith("\n")) str_for_match = str_for_match.Remove(str_for_match.Length - 1); if (reverse) { if (!re.value.RightToLeft) re.value = new System.Text.RegularExpressions.Regex(re.pattern, re.value.Options | System.Text.RegularExpressions.RegexOptions.RightToLeft); regs = re.value.Match(str_for_match, 0, pos + 1); } else { if (re.value.RightToLeft) re.value = new System.Text.RegularExpressions.Regex(re.pattern, re.value.Options ^ System.Text.RegularExpressions.RegexOptions.RightToLeft); regs = re.value.Match(str_for_match, pos, str_for_match.Length - pos); } if (regs.Success) result = regs.Index; else result = -1; if (result < 0) { rb_backref_set(null, caller); return result; } match = rb_backref_get(caller); if (match == null || match.busy) { match = new Match(Ruby.Runtime.Init.rb_cMatch); } else { if (Eval.rb_safe_level() >= 3) match.Tainted = true; else match.Tainted = false; } match.value = regs; match.matched = str.value; rb_backref_set(match, caller); Object.obj_infect(match, re); Object.obj_infect(match, str); return result; }
internal static void rb_backref_set(Match val, Frame caller) // status: done { caller.Tilde = val; }