private bool Match(RubyRegex /*!*/ pattern, bool currentPositionOnly, bool advancePosition) { Match match = pattern.Match(_scanString, _currentPosition); _lastMatch = null; _lastMatchingGroups = null; _foundPosition = 0; if (!match.Success) { return(false); } if (currentPositionOnly && match.Index != _currentPosition) { return(false); } int length = (match.Index - _currentPosition) + match.Length; _foundPosition = match.Index; _previousPosition = _currentPosition; _lastMatch = _scanString.GetSlice(_foundPosition, match.Length); _lastMatchingGroups = match.Groups; if (advancePosition) { _currentPosition += length; } return(true); }
private bool Match(RubyRegex /*!*/ pattern, bool currentPositionOnly, bool advancePosition) { // TODO: repeated calls on the same ScanString can be optimized: MatchData match = pattern.Match(null, _scanString, _currentPosition, false); _lastMatch = null; _lastMatchingGroups = null; _foundPosition = 0; if (match == null) { return(false); } if (currentPositionOnly && match.Index != _currentPosition) { return(false); } int length = (match.Index - _currentPosition) + match.Length; _foundPosition = match.Index; _previousPosition = _currentPosition; _lastMatch = _scanString.GetSlice(_foundPosition, match.Length); _lastMatchingGroups = match; if (advancePosition) { _currentPosition += length; } return(true); }
public static Node /*!*/ ToYaml(RubyRegex /*!*/ self, [NotNull] RubyRepresenter /*!*/ rep) { return(rep.Scalar( rep.GetTagUri(self), self.Inspect().ToAsciiString(), ScalarQuotingStyle.None )); }
public static Node /*!*/ ToYaml(RubyRegex /*!*/ self, [NotNull] RubyRepresenter /*!*/ rep) { return(rep.Scalar( rep.GetTagUri(self), self.Inspect().ToAsciiString(rep.Context.RubyOptions.Compatibility < RubyCompatibility.Ruby19), ScalarQuotingStyle.None )); }
public static int?Exist(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { if (!self.Match(pattern, false, false)) { return(null); } return(self.FoundPosition + self.LastMatch.Length); }
public static int?Match(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { if (!self.Match(pattern, true, false)) { return(null); } return(self.LastMatch.GetLength()); }
public static int?SkipUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { bool match = self.Match(pattern, false, true); if (!match) { return(null); } return(self.CurrentPosition - self.PreviousPosition); }
public static object AddDomainType(RubyContext /*!*/ context, BlockParam /*!*/ block, RubyModule /*!*/ self, MutableString /*!*/ domainAndDate, RubyRegex /*!*/ typeRegex) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } MutableString tag = MutableString.Create("tag:"). Append(domainAndDate).Append(":"). Append(typeRegex.GetPattern()); RubyConstructor.AddExternalMultiConstructor(tag.ConvertToString(), block); return(null); }
public static object AddDomainType(RubyContext/*!*/ context, BlockParam/*!*/ block, RubyModule/*!*/ self, MutableString/*!*/ domainAndDate, RubyRegex/*!*/ typeRegex) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } MutableString tag = MutableString.CreateMutable(typeRegex.Encoding). Append("tag:"). Append(domainAndDate). Append(':'). Append(typeRegex.Pattern); RubyConstructor.AddExternalMultiConstructor(tag.ConvertToString(), block); return null; }
public static object ScanFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advancePointer, bool returnString) { bool match = self.Match(pattern, true, advancePointer); if (match) { if (returnString) { return(MutableString.Create(self.LastMatch)); } else { return(ScriptingRuntimeHelpers.Int32ToObject(self.LastMatch.Length)); } } return(null); }
public static object ScanFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advance_pointer_p, bool return_string_p) { bool match = self.Match(pattern, true, advance_pointer_p); object result = null; if (match) { if (return_string_p) { result = MutableString.Create(self.LastMatch); } else { result = self.LastMatch.Length; } } return(result); }
public static object SearchFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advancePointer, bool returnString) { bool match = self.Match(pattern, false, advancePointer); if (match) { int length = self.LastMatch.Length + (self.FoundPosition - self.PreviousPosition); if (returnString) { return(self.ScanString.GetSlice(self.PreviousPosition, length)); } else { return(ScriptingRuntimeHelpers.Int32ToObject(length)); } } return(null); }
public static object SearchFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advance_pointer_p, bool return_string_p) { bool match = self.Match(pattern, false, advance_pointer_p); object result = null; if (match) { int length = self.LastMatch.Length + (self.FoundPosition - self.PreviousPosition); if (return_string_p) { result = self.ScanString.GetSlice(self.PreviousPosition, length); } else { result = length; } } return(result); }
public void RegexEscape1() { string[] patterns = new string[] { @"", @"", @"\", @"\\", @"(*)", @"\(\*\)", "$_^_|_[_]_(_)_\\_._#_-_{_}_*_+_?_\t_\n_\r_\f_\v_\a_\b", @"\$_\^_\|_\[_\]_\(_\)_\\_\._\#_\-_\{_\}_\*_\+_\?_\t_\n_\r_\f_" + "\v_\a_\b" }; for (int i = 0; i < patterns.Length; i += 2) { string expected = patterns[i + 1]; string actual = RubyRegex.Escape(patterns[i]); Assert(actual == expected); } }
public void RegexEncoding1() { MatchData m; // the k-coding of the pattern string is irrelevant: foreach (var pe in new[] { RubyEncoding.KCodeSJIS, RubyEncoding.KCodeUTF8, RubyEncoding.Binary }) { var p = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, pe); var r = new RubyRegex(p, RubyRegexOptions.NONE); var rs = new RubyRegex(p, RubyRegexOptions.SJIS); // the k-coding of the string is irrelevant: foreach (var se in new[] { RubyEncoding.KCodeSJIS, RubyEncoding.KCodeUTF8, RubyEncoding.Binary }) { var s = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0 }, se); var t = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0, 0x82, 0xa0, 0xa0, 0xff }, se); var u = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0x82, 0xa0, 0x82, 0xa0 }, se); // /あ{2}/ does not match "あ\xa0" m = r.Match(RubyEncoding.KCodeSJIS, s); Assert(m == null); // /\x82\xa0{2}/ matches "[ \x82\xa0\xa0 ] \x82\xa0\xa0\xff" m = r.Match(null, s); Assert(m != null && m.Index == 0); // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" starting from byte #1: m = r.Match(null, t, 1, false); Assert(m != null && m.Index == 3 && m.Length == 3); // /あ{2}/s does not match "あ\xa0", current KCODE is ignored m = rs.Match(null, s); Assert(m == null); // /あ{2}/s does not match "あ\xa0", current KCODE is ignored m = rs.Match(RubyEncoding.KCodeUTF8, s); Assert(m == null); // /あ{2}/s matches "ああ\xff", current KCODE is ignored m = rs.Match(RubyEncoding.KCodeUTF8, u, 2, false); Assert(m != null && m.Index == 2 && m.Length == 4); // /あ{2}/ does not match "あ\xa0あ\xa0" m = r.LastMatch(RubyEncoding.KCodeSJIS, t); Assert(m == null); // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" m = r.LastMatch(null, t); Assert(m != null && m.Index == 3); // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored m = rs.LastMatch(null, t); Assert(m == null); // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored m = rs.LastMatch(RubyEncoding.KCodeUTF8, t); Assert(m == null); } } }
public void RegexEncoding2() { var SJIS = RubyEncoding.KCodeSJIS.StrictEncoding; // 1.9 encodings: var invalidUtf8 = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8); AssertExceptionThrown<ArgumentException>(() => new RubyRegex(invalidUtf8, RubyRegexOptions.NONE)); // LastMatch MatchData m; var u = MutableString.CreateBinary(SJIS.GetBytes("あああ"), RubyEncoding.KCodeSJIS); var p = MutableString.CreateBinary(SJIS.GetBytes("あ{2}"), RubyEncoding.KCodeSJIS); var rs = new RubyRegex(p, RubyRegexOptions.SJIS); // /あ{2}/ matches "あああ", the resulting index is in bytes: m = rs.LastMatch(null, u); Assert(m != null && m.Index == 2); rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("あ")), RubyRegexOptions.SJIS); // "start at" in the middle of a character: m = rs.LastMatch(null, u, 0); Assert(m != null && m.Index == 0); m = rs.LastMatch(null, u, 1); Assert(m != null && m.Index == 0); m = rs.LastMatch(null, u, 2); Assert(m != null && m.Index == 2); m = rs.LastMatch(null, u, 3); Assert(m != null && m.Index == 2); // Split u = MutableString.CreateBinary(SJIS.GetBytes("あちあちあ"), RubyEncoding.UTF8); rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち")), RubyRegexOptions.SJIS); var parts = rs.Split(null, u); Assert(parts.Length == 3); foreach (var part in parts) { Assert(part.Encoding == RubyEncoding.KCodeSJIS); Assert(part.ToString() == "あ"); } // groups rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち(a(あ+)(b+))+あ")), RubyRegexOptions.SJIS); u = MutableString.CreateBinary(SJIS.GetBytes("ちaああbaあbbbあ")); m = rs.Match(null, u); Assert(m.GroupCount == 4); int s, l; Assert(m.GetGroupStart(0) == (s = 0)); Assert(m.GetGroupLength(0) == (l = u.GetByteCount())); Assert(m.GetGroupEnd(0) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(1) == (s = SJIS.GetByteCount("ちaああb"))); Assert(m.GetGroupLength(1) == (l = SJIS.GetByteCount("aあbbb"))); Assert(m.GetGroupEnd(1) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(2) == (s = SJIS.GetByteCount("ちaああba"))); Assert(m.GetGroupLength(2) == (l = SJIS.GetByteCount("あ"))); Assert(m.GetGroupEnd(2) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(3) == (s = SJIS.GetByteCount("ちaああbaあ"))); Assert(m.GetGroupLength(3) == (l = SJIS.GetByteCount("bbb"))); Assert(m.GetGroupEnd(3) == s + l); }
private static object BlockReplaceInPlace(RubyScope/*!*/ scope, BlockParam/*!*/ block, MutableString/*!*/ self, RubyRegex/*!*/ pattern, bool replaceAll) { object blockResult; uint version = self.Version; // prepare replacement in a builder: MutableString builder; if (replaceAll ? BlockReplaceAll(scope, self, block, pattern, out blockResult, out builder) : BlockReplaceFirst(scope, self, block, pattern, out blockResult, out builder)) { // block jumped: return blockResult; } // unsuccessful match: if (builder == null) { return null; } RequireNoVersionChange(version, self); if (self.IsFrozen) { throw new RuntimeError("string frozen"); } // replace content of self with content of the builder: self.Replace(0, self.Length, builder); return self.TaintBy(builder); }
public static MutableString CheckUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { return(SearchFull(self, pattern, false, true) as MutableString); }
private static MutableString ReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, RubyRegex/*!*/ pattern) { MatchData match = RegexpOps.Match(scope, pattern, input); if (match == null || !match.Success) { return null; } MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement); // prematch: result.Append(input, 0, match.Index); AppendReplacementExpression(input, match, result, replacement); // postmatch: int offset = match.Index + match.Length; result.Append(input, offset, input.Length - offset); return result; }
public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE); return BlockReplaceFirst(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); }
public void MutableString_IndexRegex1() { var SJIS = RubyEncoding.GetRubyEncoding(RubyEncoding.CodePageSJIS); var sjis = new byte[] { 0x82, 0xA0 }; var u12345 = new byte[] { 0xF0, 0x92, 0x8D, 0x85 }; // \u{12345} in UTF-8 var invalid = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8); int i; MutableString a; RubyRegex r; RubyScope scope = new RubyTopLevelScope(Context); // incompatible encodings: a = MutableString.CreateBinary(sjis, SJIS); r = new RubyRegex(MutableString.CreateBinary(u12345, RubyEncoding.UTF8)); AssertExceptionThrown<EncodingCompatibilityError>(() => MutableStringOps.Index(scope, a, r, 0)); // invalid character: AssertExceptionThrown<ArgumentException>(() => MutableStringOps.Index(scope, invalid, r, 0)); // returns character index: i = (int)MutableStringOps.Index( scope, MutableString.CreateMutable("aαb", RubyEncoding.UTF8), new RubyRegex(MutableString.CreateMutable("b", SJIS)), 0 ); Assert(i == 2); // "start at" counts chars in 1.9, returns character index i = (int)MutableStringOps.Index( scope, MutableString.CreateMutable("αabbba", RubyEncoding.UTF8), new RubyRegex(MutableString.CreateAscii("a")), 2 ); Assert(i == 5); // "start at" counts bytes in 1.8, returns byte index (regardless of KCODE) i = (int)MutableStringOps.Index( scope, MutableString.CreateBinary(Encoding.UTF8.GetBytes("αa"), RubyEncoding.Binary), new RubyRegex(MutableString.CreateAscii("a"), RubyRegexOptions.UTF8), 2 ); Assert(i == 2); // returns byte index for k-coded strings: i = (int)MutableStringOps.Index( scope, MutableString.CreateMutable("αaβb", RubyEncoding.KCodeUTF8), new RubyRegex(MutableString.CreateMutable("a", RubyEncoding.KCodeSJIS)), 0 ); Assert(i == 2); // returns byte index for k-coded strings: i = (int)MutableStringOps.Index( scope, MutableString.CreateMutable("αabbba", RubyEncoding.KCodeUTF8), new RubyRegex(MutableString.CreateAscii("a")), 2 ); Assert(i == 2); // uses the current KCODE for match: a = MutableString.CreateBinary(new byte[] { 0x82, 0xa1, 0x82, 0xa0, 0x82, 0xa0 }, RubyEncoding.Binary); r = new RubyRegex(MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, RubyEncoding.Binary)); Context.KCode = RubyEncoding.KCodeSJIS; Assert((int)MutableStringOps.Index(scope, a, r, 0) == 2); Context.KCode = null; Assert(MutableStringOps.Index(scope, a, r, 0) == null); // invalid characters: a = MutableString.CreateBinary(new byte[] { 0x82, 0x82, 0xa0, 0xa0, 0x82 }, RubyEncoding.Binary); // invalid r = new RubyRegex(MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, RubyEncoding.Binary)); // valid Context.KCode = RubyEncoding.KCodeSJIS; Assert(MutableStringOps.Index(scope, a, r, 0) == null); Context.KCode = null; Assert((int)MutableStringOps.Index(scope, a, r, 0) == 1); }
public static object /*!*/ Scan(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { return(ScanFull(self, pattern, true, true)); }
private Subclass(RubyRegex.Subclass/*!*/ regex) : base(regex) { _class = regex._class; }
public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; // TODO: var regex = new RubyRegex(MutableString.CreateMutable(Regex.Escape(matchString.ToString()), matchString.Encoding), RubyRegexOptions.NONE); self.TrackChanges(); object r = BlockReplaceAll(tosConversion, scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(self); return r; }
public static Node/*!*/ ToYaml(RubyRegex/*!*/ self, [NotNull]RubyRepresenter/*!*/ rep) { return rep.Scalar(self, rep.Context.Inspect(self)); }
public void RegexEncoding1() { MatchData m; // the k-coding of the pattern string is irrelevant: foreach (var pe in new[] { RubyEncoding.Binary }) { var p = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, pe); var r = new RubyRegex(p, RubyRegexOptions.NONE); var rs = new RubyRegex(p, RubyRegexOptions.SJIS); // the k-coding of the string is irrelevant: foreach (var se in new[] { RubyEncoding.Binary }) { var s = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0 }, se); var t = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0, 0x82, 0xa0, 0xa0, 0xff }, se); var u = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0x82, 0xa0, 0x82, 0xa0 }, se); // /あ{2}/ does not match "あ\xa0" m = r.Match(RubyEncoding.KCodeSJIS, s); Assert(m == null); // /\x82\xa0{2}/ matches "[ \x82\xa0\xa0 ] \x82\xa0\xa0\xff" m = r.Match(null, s); Assert(m != null && m.Index == 0); // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" starting from byte #1: m = r.Match(null, t, 1, false); Assert(m != null && m.Index == 3 && m.Length == 3); // /あ{2}/s does not match "あ\xa0", current KCODE is ignored m = rs.Match(null, s); Assert(m == null); // /あ{2}/s does not match "あ\xa0", current KCODE is ignored m = rs.Match(RubyEncoding.KCodeUTF8, s); Assert(m == null); // /あ{2}/s matches "ああ\xff", current KCODE is ignored m = rs.Match(RubyEncoding.KCodeUTF8, u, 2, false); Assert(m != null && m.Index == 2 && m.Length == 4); // /あ{2}/ does not match "あ\xa0あ\xa0" m = r.LastMatch(RubyEncoding.KCodeSJIS, t); Assert(m == null); // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" m = r.LastMatch(null, t); Assert(m != null && m.Index == 3); // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored m = rs.LastMatch(null, t); Assert(m == null); // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored m = rs.LastMatch(RubyEncoding.KCodeUTF8, t); Assert(m == null); } } }
public static MutableString Scan(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { return(ScanFull(self, pattern, true, true) as MutableString); }
private bool Match(RubyRegex/*!*/ pattern, bool currentPositionOnly, bool advancePosition) { Match match = pattern.Match(_scanString, _currentPosition); _lastMatch = null; _lastMatchingGroups = null; _foundPosition = 0; if (!match.Success) { return false; } if (currentPositionOnly && match.Index != _currentPosition) { return false; } int length = (match.Index - _currentPosition) + match.Length; _foundPosition = match.Index; _previousPosition = _currentPosition; _lastMatch = _scanString.GetSlice(_foundPosition, match.Length); _lastMatchingGroups = match.Groups; if (advancePosition) { _currentPosition += length; } return true; }
// returns true if block jumped // "result" will be null if there is no successful match private static bool BlockReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block, RubyRegex/*!*/ pattern, out object blockResult, out MutableString result) { var matchScope = scope.GetInnerMostClosureScope(); MatchData match = RegexpOps.Match(scope, pattern, input); if (match == null || !match.Success) { result = null; blockResult = null; matchScope.CurrentMatch = null; return false; } // copy upfront so that no modifications to the input string are included in the result: result = input.Clone(); matchScope.CurrentMatch = match; if (block.Yield(MutableString.Create(match.Value), out blockResult)) { return true; } // resets the $~ scope variable to the last match (skipd if block jumped): matchScope.CurrentMatch = match; MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult); result.TaintBy(replacement); // Note - we don't interpolate special sequences like \1 in block return value result.Replace(match.Index, match.Length, replacement); blockResult = null; return false; }
public static object ImplicitMatch(ConversionStorage<MutableString>/*!*/ stringCast, RubyScope/*!*/ scope, RubyRegex/*!*/ self) { return MatchIndex(scope, self, Protocols.CastToString(stringCast, scope.GetInnerMostClosureScope().LastInputLine)); }
public static object ScanUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern) { return(SearchFull(self, pattern, true, true)); }
public void RegexEncoding2() { var SJIS = RubyEncoding.KCodeSJIS.StrictEncoding; // 1.9 encodings: var invalidUtf8 = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8); AssertExceptionThrown <ArgumentException>(() => new RubyRegex(invalidUtf8, RubyRegexOptions.NONE)); // LastMatch MatchData m; var u = MutableString.CreateBinary(SJIS.GetBytes("あああ"), RubyEncoding.KCodeSJIS); var p = MutableString.CreateBinary(SJIS.GetBytes("あ{2}"), RubyEncoding.KCodeSJIS); var rs = new RubyRegex(p, RubyRegexOptions.SJIS); // /あ{2}/ matches "あああ", the resulting index is in bytes: m = rs.LastMatch(null, u); Assert(m != null && m.Index == 2); rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("あ")), RubyRegexOptions.SJIS); // "start at" in the middle of a character: m = rs.LastMatch(null, u, 0); Assert(m != null && m.Index == 0); m = rs.LastMatch(null, u, 1); Assert(m != null && m.Index == 0); m = rs.LastMatch(null, u, 2); Assert(m != null && m.Index == 2); m = rs.LastMatch(null, u, 3); Assert(m != null && m.Index == 2); // Split u = MutableString.CreateBinary(SJIS.GetBytes("あちあちあ"), RubyEncoding.UTF8); rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち")), RubyRegexOptions.SJIS); var parts = rs.Split(null, u); Assert(parts.Length == 3); foreach (var part in parts) { Assert(part.Encoding == RubyEncoding.KCodeSJIS); Assert(part.ToString() == "あ"); } // groups rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち(a(あ+)(b+))+あ")), RubyRegexOptions.SJIS); u = MutableString.CreateBinary(SJIS.GetBytes("ちaああbaあbbbあ")); m = rs.Match(null, u); Assert(m.GroupCount == 4); int s, l; Assert(m.GetGroupStart(0) == (s = 0)); Assert(m.GetGroupLength(0) == (l = u.GetByteCount())); Assert(m.GetGroupEnd(0) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(1) == (s = SJIS.GetByteCount("ちaああb"))); Assert(m.GetGroupLength(1) == (l = SJIS.GetByteCount("aあbbb"))); Assert(m.GetGroupEnd(1) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(2) == (s = SJIS.GetByteCount("ちaああba"))); Assert(m.GetGroupLength(2) == (l = SJIS.GetByteCount("あ"))); Assert(m.GetGroupEnd(2) == s + l); // the group has 2 captures, the last one is its value: Assert(m.GetGroupStart(3) == (s = SJIS.GetByteCount("ちaああbaあ"))); Assert(m.GetGroupLength(3) == (l = SJIS.GetByteCount("bbb"))); Assert(m.GetGroupEnd(3) == s + l); }
public static MutableString/*!*/ Source(RubyRegex/*!*/ self) { return self.GetPattern(); }
public static MutableString/*!*/ TagUri(RubyRegex/*!*/ self) { return MutableString.Create("tag:ruby.yaml.org,2002:regexp"); }
public static RubyRegex/*!*/ Reinitialize(RubyRegex/*!*/ self, [NotNull]RubyRegex/*!*/ other) { self.Set(other.GetPattern(), other.Options); return self; }
// returns true if block jumped // "result" will be null if there is no successful match private static bool BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block, RubyRegex/*!*/ regex, out object blockResult, out MutableString result) { var matchScope = scope.GetInnerMostClosureScope(); var matches = regex.Matches(tosConversion.Context.KCode, input); if (matches.Count == 0) { result = null; blockResult = null; matchScope.CurrentMatch = null; return false; } // create an empty result: result = input.CreateInstance().TaintBy(input); int offset = 0; foreach (MatchData match in matches) { matchScope.CurrentMatch = match; input.TrackChanges(); if (block.Yield(match.GetValue(), out blockResult)) { return true; } if (input.HasChanged) { return false; } // resets the $~ scope variable to the last match (skipd if block jumped): matchScope.CurrentMatch = match; MutableString replacement = Protocols.ConvertToString(tosConversion, blockResult); result.TaintBy(replacement); // prematch: result.Append(input, offset, match.Index - offset); // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value): result.Append(replacement); offset = match.Index + match.Length; } // post-last-match: result.Append(input, offset, input.Length - offset); blockResult = null; return false; }
public static RubyRegex/*!*/ Reinitialize(RubyContext/*!*/ context, RubyRegex/*!*/ self, [NotNull]RubyRegex/*!*/ regex, int options, [Optional]object encoding) { ReportParametersIgnoredWarning(context, encoding); return Reinitialize(self, regex); }
private static object MatchToScanResult(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, MatchData/*!*/ match) { if (match.GroupCount == 1) { return match.GetValue().TaintBy(regex, scope); } else { var result = new RubyArray(match.GroupCount - 1); for (int i = 1; i < match.GroupCount; i++) { MutableString value = match.GetGroupValue(i); result.Add(value != null ? value.TaintBy(regex, scope) : value); } return result; } }
public static RubyRegex/*!*/ Reinitialize(RubyContext/*!*/ context, RubyRegex/*!*/ self, [NotNull]RubyRegex/*!*/ regex, [DefaultParameterValue(null)]object ignoreCase, [Optional]object encoding) { ReportParametersIgnoredWarning(context, encoding); return Reinitialize(self, regex); }
private bool Match(RubyRegex/*!*/ pattern, bool currentPositionOnly, bool advancePosition) { // TODO: repeated calls on the same ScanString can be optimized: MatchData match = pattern.Match(_scanString, _currentPosition, false); _lastMatch = null; _lastMatchingGroups = null; _foundPosition = 0; if (match == null) { return false; } if (currentPositionOnly && match.Index != _currentPosition) { return false; } int length = (match.Index - _currentPosition) + match.Length; _foundPosition = match.Index; _previousPosition = _currentPosition; _lastMatch = _scanString.GetSlice(_foundPosition, match.Length); _lastMatchingGroups = match; if (advancePosition) { _currentPosition += length; } return true; }
public static RubyRegex/*!*/ Reinitialize(RubyRegex/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ pattern, int options, [DefaultProtocol, Optional]MutableString encoding) { self.Set(pattern, MakeOptions(options, encoding)); return self; }
// returns true if block jumped // "result" will be null if there is no successful match private static bool BlockReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block, RubyRegex/*!*/ regex, out object blockResult, out MutableString result) { var matchScope = scope.GetInnerMostClosureScope(); MatchCollection matches = regex.Matches(input); if (matches.Count == 0) { result = null; blockResult = null; matchScope.CurrentMatch = null; return false; } // create an empty result: result = input.CreateInstance().TaintBy(input); int offset = 0; foreach (Match match in matches) { MatchData currentMatch = new MatchData(match, input); matchScope.CurrentMatch = currentMatch; uint version = input.Version; if (block.Yield(MutableString.Create(match.Value), out blockResult)) { return true; } if (input.Version != version) { return false; } // resets the $~ scope variable to the last match (skipd if block jumped): matchScope.CurrentMatch = currentMatch; MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult); result.TaintBy(replacement); // prematch: result.Append(input, offset, match.Index - offset); // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value): result.Append(replacement); offset = match.Index + match.Length; } // post-last-match: result.Append(input, offset, input.Length - offset); blockResult = null; return false; }
private void WriteRegex(RubyRegex/*!*/ value) { SubclassData instanceWriter = new SubclassData(this, value, typeof(RubyRegex)); _writer.Write((byte)'/'); WriteStringValue(value.GetPattern()); _writer.Write((byte)value.Options); }
private static MutableString ReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, RubyRegex/*!*/ regex) { var matchScope = scope.GetInnerMostClosureScope(); // case of all MatchCollection matches = regex.Matches(input); if (matches.Count == 0) { matchScope.CurrentMatch = null; return null; } MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement); int offset = 0; foreach (Match match in matches) { result.Append(input, offset, match.Index - offset); AppendReplacementExpression(input, match, result, replacement); offset = match.Index + match.Length; } result.Append(input, offset, input.Length - offset); matchScope.CurrentMatch = new MatchData(matches[matches.Count - 1], input); return result; }
private static object MatchToScanResult(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, Match/*!*/ match) { if (match.Groups.Count == 1) { return MutableString.Create(match.Value).TaintBy(self).TaintBy(regex, scope); } else { var result = new RubyArray(match.Groups.Count - 1); for (int i = 1; i < match.Groups.Count; i++) { if (match.Groups[i].Success) { result.Add(MutableString.Create(match.Groups[i].Value).TaintBy(self).TaintBy(regex, scope)); } else { result.Add(null); } } return result; } }
public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE); uint version = self.Version; object r = BlockReplaceAll(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(version, self); return r; }
public static MutableString TagUri([NotNull] RubyRegex self) { return(MutableString.Create("tag:ruby.yaml.org,2002:regexp")); }
private static MutableString ReplaceInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ pattern, MutableString/*!*/ replacement, bool replaceAll) { MutableString builder = replaceAll ? ReplaceAll(scope, self, replacement, pattern) : ReplaceFirst(scope, self, replacement, pattern); // unsuccessful match: if (builder == null) { return null; } self.Replace(0, self.Length, builder); return self.TaintBy(builder); }
private void WriteRegex(RubyRegex/*!*/ value) { WriteSubclassData(value, typeof(RubyRegex)); _writer.Write((byte)'/'); WriteStringValue(value.Pattern); _writer.Write((byte)value.Options); }
private static Group MatchRegexp(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, int occurrance) { MatchData match = RegexpOps.Match(scope, regex, self); if (match == null || !match.Success) return null; // Normalize index against # Groups in Match if (occurrance < 0) { occurrance += match.Groups.Count; // Cannot refer to zero using negative indices if (occurrance == 0) { return null; } } if (occurrance < 0 || occurrance > match.Groups.Count) { return null; } return match.Groups[occurrance].Success ? match.Groups[occurrance] : null; }
public static MutableString /*!*/ TagUri(RubyContext /*!*/ context, RubyRegex /*!*/ self) { return(RubyYaml.GetTagUri(context, self, Tags.RubyRegexp, typeof(RubyRegex))); }