public static object match(object thisObj, VsaEngine engine, object regExp) { string string_obj = Convert.ToString(thisObj); RegExpObject regex_obj = Convert.ToRegExp(regExp); bool global = regex_obj.global; if (!global) { return(RegExpPrototype.exec(regex_obj, string_obj)); } MatchCollection md = regex_obj.regex.Matches(string_obj); uint n = (uint)md.Count; Match lastMatch = md [(int)(n - 1)]; regex_obj.lastIndex = lastMatch.Index + 1; RegExpConstructor.UpdateLastMatch(lastMatch, string_obj); ArrayObject result = new ArrayObject(); result.length = n; for (uint i = 0; i < n; i++) { result.elems [i] = md [(int)i].Value; } return(result); }
public static object exec(object thisObj, object input) { RegExpObject re = Convert.ToRegExp(thisObj); string str = null; if (input == null) { RegExpConstructor ctr = RegExpConstructor.Ctr; str = Convert.ToString(ctr.GetField("$_").GetValue("$_")); } else { str = Convert.ToString(input); } bool global = re.global; int lastIndex = global ? (int)((double)re.lastIndex) : 0; bool success = lastIndex >= 0 && lastIndex <= str.Length; Match md = null; if (success) { md = re.regex.Match(str, lastIndex); success = md.Success; } if (!success) { re.lastIndex = 0; return(DBNull.Value); } int index = md.Index; int endIndex = index + md.Length; if (global) { re.lastIndex = endIndex; } RegExpConstructor.UpdateLastMatch(md, str); GroupCollection caps = md.Groups; uint len = (uint)caps.Count; RegExpMatch result = new RegExpMatch(); result.AddField("index", index); result.AddField("input", input); result.length = len; for (uint j = 0; j < len; j++) { result.elems [j] = caps [(int)j].Value; } return(result); }
public static ArrayObject split(object thisObj, VsaEngine engine, object separator, object limit) { string string_obj = Convert.ToString(thisObj); int length = string_obj.Length; int max_count = (limit != null) ? Convert.ToInt32(limit) : -1; ArrayObject result = new ArrayObject(); if (separator == null) { result.length = (uint)1; result.elems [(uint)0] = string_obj; return(result); } int start_pos = 0; int end_pos = -1; int match_len = 0; uint count = 0; int sep_len = 0; if (!(separator is RegExpObject)) { string sep_str = Convert.ToString(separator); sep_len = sep_str.Length; if (string_obj.Length == 0) { if (sep_len > 0) { result.length = (uint)1; result.elems [(uint)0] = string_obj; } return(result); } while (end_pos != length && (max_count == -1 || count < max_count)) { end_pos = (length != 0) ? string_obj.IndexOf(sep_str, start_pos) : length; if (end_pos == -1) { end_pos = length; } else if (sep_len == 0) { end_pos++; } match_len = end_pos - start_pos; result.elems [count] = string_obj.Substring(start_pos, match_len); start_pos += match_len + sep_len; count++; } result.length = count; return(result); } RegExpObject sep_re = (RegExpObject)separator; MatchCollection md = sep_re.regex.Matches(string_obj); uint n = (uint)md.Count; Match match = null; for (int i = 0; i < n; i++) { if (max_count != -1 && count >= max_count) { break; } match = md [i]; sep_len = match.Length; end_pos = match.Index; match_len = end_pos - start_pos; // // The specification says that "ab".split(/a*/) is ["", "b"], but would // that would also mean that "abcdef".split(/./).length would not be 6. // I'm currently going with the Rhino behavior that seems to make more // sense. // if (!(end_pos == 0 && sep_len == 0)) { result.elems [count] = string_obj.Substring(start_pos, match_len); count++; } bool first_cap = true; foreach (Capture cap in match.Groups) { if (max_count != -1 && count >= max_count) { break; } if (first_cap) { first_cap = false; continue; } result.elems [count] = cap.Value; count++; } start_pos += match_len + sep_len; } if (n > 0 && (max_count == -1 || count < max_count)) { sep_re.lastIndex = match.Index + match.Length; RegExpConstructor.UpdateLastMatch(match, string_obj); if (start_pos < length) { result.elems [count] = string_obj.Substring(start_pos); count++; } } else if (n == 0) { result.elems [(uint)0] = string_obj; count++; } result.length = count; return(result); }