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; }
// 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; }
// 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 static MutableString ReplaceAll(ConversionStorage<MutableString> toS, BinaryOpStorage hashDefault, RubyScope/*!*/ scope, MutableString/*!*/ input, Union<IDictionary<object, object>, MutableString>/*!*/ replacement, RubyRegex/*!*/ regex) { var matchScope = scope.GetInnerMostClosureScope(); IList<MatchData> matches = regex.Matches(scope.RubyContext.KCode, input); if (matches.Count == 0) { matchScope.CurrentMatch = null; return null; } MutableString result = input.CreateInstance().TaintBy(input); int offset = 0; foreach (MatchData match in matches) { result.Append(input, offset, match.Index - offset); AppendReplacementExpression(toS, hashDefault, input, match, result, replacement); offset = match.Index + match.Length; } result.Append(input, offset, input.Length - offset); matchScope.CurrentMatch = matches[matches.Count - 1]; return result; }