Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Regex / System / Text / RegularExpressions / RegexReplacement.cs / 1 / RegexReplacement.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
// The RegexReplacement class represents a substitution string for
// use when using regexs to search/replace, etc. It's logically
// a sequence intermixed (1) constant strings and (2) group numbers.
namespace System.Text.RegularExpressions {
using System.Collections;
internal sealed class RegexReplacement {
/*
* Since RegexReplacement shares the same parser as Regex,
* the constructor takes a RegexNode which is a concatenation
* of constant strings and backreferences.
*/
internal RegexReplacement(String rep, RegexNode concat, Hashtable _caps) {
StringBuilder sb;
ArrayList strings;
ArrayList rules;
int slot;
_rep = rep;
if (concat.Type() != RegexNode.Concatenate)
throw new ArgumentException(SR.GetString(SR.ReplacementError));
sb = new StringBuilder();
strings = new ArrayList();
rules = new ArrayList();
for (int i = 0; i < concat.ChildCount(); i++) {
RegexNode child = concat.Child(i);
switch (child.Type()) {
case RegexNode.Multi:
sb.Append(child._str);
break;
case RegexNode.One:
sb.Append(child._ch);
break;
case RegexNode.Ref:
if (sb.Length > 0) {
rules.Add(strings.Count);
strings.Add(sb.ToString());
sb.Length = 0;
}
slot = child._m;
if (_caps != null && slot >= 0)
slot = (int)_caps[slot];
rules.Add(-Specials - 1 - slot);
break;
default:
throw new ArgumentException(SR.GetString(SR.ReplacementError));
}
}
if (sb.Length > 0) {
rules.Add(strings.Count);
strings.Add(sb.ToString());
}
_strings = strings;
_rules = rules;
}
internal String _rep;
internal ArrayList _strings; // table of string constants
internal ArrayList _rules; // negative -> group #, positive -> string #
// constants for special insertion patterns
internal const int Specials = 4;
internal const int LeftPortion = -1;
internal const int RightPortion = -2;
internal const int LastGroup = -3;
internal const int WholeString = -4;
/*
* Given a Match, emits into the StringBuilder the evaluated
* substitution pattern.
*/
private void ReplacementImpl(StringBuilder sb, Match match) {
for (int i = 0; i < _rules.Count; i++) {
int r = (int) _rules[i];
if (r >= 0)
sb.Append((string) _strings[r]);
else if (r < -Specials)
sb.Append(match.GroupToStringImpl(-Specials - 1 - r));
else {
switch (-Specials - 1 - r) {
case LeftPortion:
sb.Append(match.GetLeftSubstring());
break;
case RightPortion:
sb.Append(match.GetRightSubstring());
break;
case LastGroup:
sb.Append(match.LastGroupToStringImpl());
break;
case WholeString:
sb.Append(match.GetOriginalString());
break;
}
}
}
}
/*
* The original pattern string
*/
internal String Pattern {
get {
return _rep;
}
}
/*
* Returns the replacement result for a single match
*/
internal String Replacement(Match match) {
StringBuilder sb = new StringBuilder();
ReplacementImpl(sb, match);
return sb.ToString();
}
/*
* Three very similar algorithms appear below: replace (pattern),
* replace (evaluator), and split.
*/
/*
* Replaces all ocurrances of the regex in the string with the
* replacement pattern.
*
* Note that the special case of no matches is handled on its own:
* with no matches, the input string is returned unchanged.
* The right-to-left case is split out because StringBuilder
* doesn't handle right-to-left string building directly very well.
*/
internal String Replace(Regex regex, String input, int count, int startat) {
Match match;
if (count < -1)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 0)
return input;
match = regex.Match(input, startat);
if (!match.Success) {
return input;
}
else {
StringBuilder sb;
if (!regex.RightToLeft) {
sb = new StringBuilder();
int prevat = 0;
do {
if (match.Index != prevat)
sb.Append(input, prevat, match.Index - prevat);
prevat = match.Index + match.Length;
ReplacementImpl(sb, match);
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
if (prevat < input.Length)
sb.Append(input, prevat, input.Length - prevat);
}
else {
ArrayList al = new ArrayList();
int prevat = input.Length;
do {
if (match.Index + match.Length != prevat)
al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length));
prevat = match.Index;
for (int i = _rules.Count - 1; i >= 0; i--) {
int r = (int) _rules[i];
if (r >= 0)
al.Add((string) _strings[r]);
else
al.Add(match.GroupToStringImpl(-Specials - 1 - r));
}
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
sb = new StringBuilder();
if (prevat > 0)
sb.Append(input, 0, prevat);
for (int i = al.Count - 1; i >= 0; i--) {
sb.Append((String)al[i]);
}
}
return sb.ToString();
}
}
/*
* Replaces all ocurrances of the regex in the string with the
* replacement evaluator.
*
* Note that the special case of no matches is handled on its own:
* with no matches, the input string is returned unchanged.
* The right-to-left case is split out because StringBuilder
* doesn't handle right-to-left string building directly very well.
*/
internal static String Replace(MatchEvaluator evaluator, Regex regex,
String input, int count, int startat) {
Match match;
if (evaluator == null)
throw new ArgumentNullException("evaluator");
if (count < -1)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 0)
return input;
match = regex.Match(input, startat);
if (!match.Success) {
return input;
}
else {
StringBuilder sb;
if (!regex.RightToLeft) {
sb = new StringBuilder();
int prevat = 0;
do {
if (match.Index != prevat)
sb.Append(input, prevat, match.Index - prevat);
prevat = match.Index + match.Length;
sb.Append(evaluator(match));
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
if (prevat < input.Length)
sb.Append(input, prevat, input.Length - prevat);
}
else {
ArrayList al = new ArrayList();
int prevat = input.Length;
do {
if (match.Index + match.Length != prevat)
al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length));
prevat = match.Index;
al.Add(evaluator(match));
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
sb = new StringBuilder();
if (prevat > 0)
sb.Append(input, 0, prevat);
for (int i = al.Count - 1; i >= 0; i--) {
sb.Append((String)al[i]);
}
}
return sb.ToString();
}
}
/*
* Does a split. In the right-to-left case we reorder the
* array to be forwards.
*/
internal static String[] Split(Regex regex, String input, int count, int startat) {
Match match;
String[] result;
if (count < 0)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 1) {
result = new String[1];
result[0] = input;
return result;
}
count -= 1;
match = regex.Match(input, startat);
if (!match.Success) {
result = new String[1];
result[0] = input;
return result;
}
else {
ArrayList al = new ArrayList();
if (!regex.RightToLeft) {
int prevat = 0;
for (;;) {
al.Add(input.Substring(prevat, match.Index - prevat));
prevat = match.Index + match.Length;
// add all matched capture groups to the list.
for (int i=1; i
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
// The RegexReplacement class represents a substitution string for
// use when using regexs to search/replace, etc. It's logically
// a sequence intermixed (1) constant strings and (2) group numbers.
namespace System.Text.RegularExpressions {
using System.Collections;
internal sealed class RegexReplacement {
/*
* Since RegexReplacement shares the same parser as Regex,
* the constructor takes a RegexNode which is a concatenation
* of constant strings and backreferences.
*/
internal RegexReplacement(String rep, RegexNode concat, Hashtable _caps) {
StringBuilder sb;
ArrayList strings;
ArrayList rules;
int slot;
_rep = rep;
if (concat.Type() != RegexNode.Concatenate)
throw new ArgumentException(SR.GetString(SR.ReplacementError));
sb = new StringBuilder();
strings = new ArrayList();
rules = new ArrayList();
for (int i = 0; i < concat.ChildCount(); i++) {
RegexNode child = concat.Child(i);
switch (child.Type()) {
case RegexNode.Multi:
sb.Append(child._str);
break;
case RegexNode.One:
sb.Append(child._ch);
break;
case RegexNode.Ref:
if (sb.Length > 0) {
rules.Add(strings.Count);
strings.Add(sb.ToString());
sb.Length = 0;
}
slot = child._m;
if (_caps != null && slot >= 0)
slot = (int)_caps[slot];
rules.Add(-Specials - 1 - slot);
break;
default:
throw new ArgumentException(SR.GetString(SR.ReplacementError));
}
}
if (sb.Length > 0) {
rules.Add(strings.Count);
strings.Add(sb.ToString());
}
_strings = strings;
_rules = rules;
}
internal String _rep;
internal ArrayList _strings; // table of string constants
internal ArrayList _rules; // negative -> group #, positive -> string #
// constants for special insertion patterns
internal const int Specials = 4;
internal const int LeftPortion = -1;
internal const int RightPortion = -2;
internal const int LastGroup = -3;
internal const int WholeString = -4;
/*
* Given a Match, emits into the StringBuilder the evaluated
* substitution pattern.
*/
private void ReplacementImpl(StringBuilder sb, Match match) {
for (int i = 0; i < _rules.Count; i++) {
int r = (int) _rules[i];
if (r >= 0)
sb.Append((string) _strings[r]);
else if (r < -Specials)
sb.Append(match.GroupToStringImpl(-Specials - 1 - r));
else {
switch (-Specials - 1 - r) {
case LeftPortion:
sb.Append(match.GetLeftSubstring());
break;
case RightPortion:
sb.Append(match.GetRightSubstring());
break;
case LastGroup:
sb.Append(match.LastGroupToStringImpl());
break;
case WholeString:
sb.Append(match.GetOriginalString());
break;
}
}
}
}
/*
* The original pattern string
*/
internal String Pattern {
get {
return _rep;
}
}
/*
* Returns the replacement result for a single match
*/
internal String Replacement(Match match) {
StringBuilder sb = new StringBuilder();
ReplacementImpl(sb, match);
return sb.ToString();
}
/*
* Three very similar algorithms appear below: replace (pattern),
* replace (evaluator), and split.
*/
/*
* Replaces all ocurrances of the regex in the string with the
* replacement pattern.
*
* Note that the special case of no matches is handled on its own:
* with no matches, the input string is returned unchanged.
* The right-to-left case is split out because StringBuilder
* doesn't handle right-to-left string building directly very well.
*/
internal String Replace(Regex regex, String input, int count, int startat) {
Match match;
if (count < -1)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 0)
return input;
match = regex.Match(input, startat);
if (!match.Success) {
return input;
}
else {
StringBuilder sb;
if (!regex.RightToLeft) {
sb = new StringBuilder();
int prevat = 0;
do {
if (match.Index != prevat)
sb.Append(input, prevat, match.Index - prevat);
prevat = match.Index + match.Length;
ReplacementImpl(sb, match);
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
if (prevat < input.Length)
sb.Append(input, prevat, input.Length - prevat);
}
else {
ArrayList al = new ArrayList();
int prevat = input.Length;
do {
if (match.Index + match.Length != prevat)
al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length));
prevat = match.Index;
for (int i = _rules.Count - 1; i >= 0; i--) {
int r = (int) _rules[i];
if (r >= 0)
al.Add((string) _strings[r]);
else
al.Add(match.GroupToStringImpl(-Specials - 1 - r));
}
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
sb = new StringBuilder();
if (prevat > 0)
sb.Append(input, 0, prevat);
for (int i = al.Count - 1; i >= 0; i--) {
sb.Append((String)al[i]);
}
}
return sb.ToString();
}
}
/*
* Replaces all ocurrances of the regex in the string with the
* replacement evaluator.
*
* Note that the special case of no matches is handled on its own:
* with no matches, the input string is returned unchanged.
* The right-to-left case is split out because StringBuilder
* doesn't handle right-to-left string building directly very well.
*/
internal static String Replace(MatchEvaluator evaluator, Regex regex,
String input, int count, int startat) {
Match match;
if (evaluator == null)
throw new ArgumentNullException("evaluator");
if (count < -1)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 0)
return input;
match = regex.Match(input, startat);
if (!match.Success) {
return input;
}
else {
StringBuilder sb;
if (!regex.RightToLeft) {
sb = new StringBuilder();
int prevat = 0;
do {
if (match.Index != prevat)
sb.Append(input, prevat, match.Index - prevat);
prevat = match.Index + match.Length;
sb.Append(evaluator(match));
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
if (prevat < input.Length)
sb.Append(input, prevat, input.Length - prevat);
}
else {
ArrayList al = new ArrayList();
int prevat = input.Length;
do {
if (match.Index + match.Length != prevat)
al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length));
prevat = match.Index;
al.Add(evaluator(match));
if (--count == 0)
break;
match = match.NextMatch();
} while (match.Success);
sb = new StringBuilder();
if (prevat > 0)
sb.Append(input, 0, prevat);
for (int i = al.Count - 1; i >= 0; i--) {
sb.Append((String)al[i]);
}
}
return sb.ToString();
}
}
/*
* Does a split. In the right-to-left case we reorder the
* array to be forwards.
*/
internal static String[] Split(Regex regex, String input, int count, int startat) {
Match match;
String[] result;
if (count < 0)
throw new ArgumentOutOfRangeException("count", SR.GetString(SR.CountTooSmall));
if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", SR.GetString(SR.BeginIndexNotNegative));
if (count == 1) {
result = new String[1];
result[0] = input;
return result;
}
count -= 1;
match = regex.Match(input, startat);
if (!match.Success) {
result = new String[1];
result[0] = input;
return result;
}
else {
ArrayList al = new ArrayList();
if (!regex.RightToLeft) {
int prevat = 0;
for (;;) {
al.Add(input.Substring(prevat, match.Index - prevat));
prevat = match.Index + match.Length;
// add all matched capture groups to the list.
for (int i=1; i
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Dispatcher.cs
- TextParagraphProperties.cs
- LoginName.cs
- TimerElapsedEvenArgs.cs
- UnsafeNativeMethodsMilCoreApi.cs
- EntityClassGenerator.cs
- Descriptor.cs
- KeyValuePairs.cs
- WindowsListViewItemCheckBox.cs
- Cursors.cs
- CustomError.cs
- ImageFormatConverter.cs
- ReachVisualSerializer.cs
- RemoteWebConfigurationHostStream.cs
- PagedControl.cs
- Debugger.cs
- GridEntryCollection.cs
- ValueOfAction.cs
- Pen.cs
- AnimationStorage.cs
- TdsParserSessionPool.cs
- DataGridViewCellStyleConverter.cs
- DateTime.cs
- DataBoundControlHelper.cs
- FormViewUpdatedEventArgs.cs
- WindowsFormsSynchronizationContext.cs
- IconBitmapDecoder.cs
- FillBehavior.cs
- ThemeableAttribute.cs
- SystemInformation.cs
- FormattedTextSymbols.cs
- CalendarAutoFormat.cs
- SystemUdpStatistics.cs
- FontFamilyConverter.cs
- Vector3DConverter.cs
- FolderLevelBuildProvider.cs
- TableParagraph.cs
- Fonts.cs
- DefaultDiscoveryService.cs
- ClipboardProcessor.cs
- InputChannelAcceptor.cs
- Logging.cs
- AbandonedMutexException.cs
- PropertyPathWorker.cs
- ProgressBarBrushConverter.cs
- InstanceDescriptor.cs
- SmtpAuthenticationManager.cs
- MatcherBuilder.cs
- IImplicitResourceProvider.cs
- SafeLibraryHandle.cs
- AnimationClock.cs
- SqlDataSource.cs
- PropertyInformationCollection.cs
- PrimarySelectionAdorner.cs
- MexNamedPipeBindingElement.cs
- SecurityKeyUsage.cs
- NameService.cs
- DetailsViewInsertedEventArgs.cs
- BuildProvidersCompiler.cs
- ConvertersCollection.cs
- XmlSchemaAppInfo.cs
- AbandonedMutexException.cs
- SHA256.cs
- CompressionTransform.cs
- EntitySqlQueryCacheEntry.cs
- DbProviderSpecificTypePropertyAttribute.cs
- SqlDelegatedTransaction.cs
- ScriptDescriptor.cs
- LiteralText.cs
- _FixedSizeReader.cs
- DoubleIndependentAnimationStorage.cs
- CipherData.cs
- Thread.cs
- SortQuery.cs
- DynamicValidatorEventArgs.cs
- SiteMapPath.cs
- TimersDescriptionAttribute.cs
- XmlBoundElement.cs
- DataGridPageChangedEventArgs.cs
- ExitEventArgs.cs
- LostFocusEventManager.cs
- SmtpReplyReaderFactory.cs
- StringConverter.cs
- InlineUIContainer.cs
- DataSetMappper.cs
- SoapMessage.cs
- InvokeBinder.cs
- Exceptions.cs
- Panel.cs
- XPathExpr.cs
- WindowAutomationPeer.cs
- IisTraceListener.cs
- ProviderMetadata.cs
- OutputCacheProfileCollection.cs
- Line.cs
- ExpressionBuilderContext.cs
- NameValuePair.cs
- ThreadExceptionDialog.cs
- XamlFxTrace.cs
- XMLUtil.cs