/// <summary> /// Start is a number of bytes if kcode is given, otherwise it's a number of characters. /// </summary> public MatchData Match(RubyEncoding kcode, MutableString /*!*/ input, int start, bool freezeInput) { string str; Regex regex = Transform(ref kcode, input, start, out str); Match match; if (kcode != null) { if (str == null) { return(null); } match = regex.Match(str, 0); } else { if (start < 0) { start += str.Length; } if (start < 0 || start > str.Length) { return(null); } match = regex.Match(str, start); } return(MatchData.Create(match, input, freezeInput, str, kcode, start)); }
public MatchData Match(MutableString /*!*/ input) { string str; RubyEncoding kcode = null; return(MatchData.Create(Transform(ref kcode, input, 0, out str).Match(str), input, true, str)); }
/// <summary> /// Finds the last match whose index is less than or equal to "start". /// Captures are ordered in the same way as with forward match. This is different from .NET reverse matching. /// Start is a number of bytes if kcode is given, otherwise it's a number of characters. /// </summary> public MatchData LastMatch(MutableString /*!*/ input, int start) { string str; RubyEncoding kcode = null; Regex regex = Transform(ref kcode, input, 0, out str); Debug.Assert(str != null); if (kcode != null) { int byteCount; byte[] bytes = input.GetByteArray(out byteCount); if (start < 0) { start += byteCount; } // GetCharCount returns the number of whole characters: start = (start >= byteCount) ? str.Length : kcode.Encoding.GetCharCount(bytes, 0, start + 1) - 1; } else { if (start < 0) { start += str.Length; } if (start > str.Length) { start = str.Length; } } Match match; if (_hasGAnchor) { // This only makes some \G anchors work. It seems that CLR doesn't support \G if preceeded by some characters. // For example, this works in MRI but doesn't in CLR: "abcabczzz".rindex(/.+\G.+/, 3) match = regex.Match(str, start); } else { match = LastMatch(regex, str, start); if (match == null) { return(null); } } return(MatchData.Create(match, input, true, str)); }
/// <summary> /// Returns a collection of fresh MatchData objects. /// </summary> public IList <MatchData> /*!*/ Matches(RubyEncoding kcode, MutableString /*!*/ input, bool inputMayMutate) { string str; MatchCollection matches = Transform(ref kcode, input, 0, out str).Matches(str); var result = new MatchData[matches.Count]; if (result.Length > 0 && inputMayMutate) { // clone and freeze the string once so that it can be shared by all the MatchData objects input = input.Clone().Freeze(); } for (int i = 0; i < result.Length; i++) { result[i] = MatchData.Create(matches[i], input, false, str, kcode, 0); } return(result); }