[英]Replace only some groups with Regex
Let's suppose I have the following regex:假设我有以下正则表达式:
-(\d+)-
and I want to replace, using C#, the Group 1 (\\d+)
with AA
, to obtain:我想使用 C# 将 Group 1
(\\d+)
替换为AA
,以获得:
-AA-
Now I'm replacing it using:现在我正在使用以下方法替换它:
var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, "-AA-");
But I don't really like this, because if I change the pattern to match _(\\d+)_
instead, I will have to change the replacement string by _AA_
too, and this is against the DRY principle.但是我真的不喜欢这样,因为如果我更改模式以匹配
_(\\d+)_
,我将不得不通过_AA_
更改替换字符串,这违反了 DRY 原则。
I'm looking for something like:我正在寻找类似的东西:
Keep the matched text exactly how it is, but change Group 1 by this text
and Group 2 by another text
...保持匹配文本的原样,但将第 1 组更改
this text
,将第 2 组更改为another text
...
Edit:编辑:
That was just an example.那只是一个例子。 I'm just looking for a generic way of doing what I said above.
我只是在寻找一种通用的方式来做我上面所说的。
It should work for:它应该适用于:
anything(\\d+)more_text
and any pattern you can imagine. anything(\\d+)more_text
和您可以想象的任何模式。
All I want to do is replace only groups, and keep the rest of the match.我想要做的就是只替换组,并保留比赛的其余部分。
A good idea could be to encapsulate everything inside groups, no matter if need to identify them or not.一个好主意可能是将所有内容封装在组中,无论是否需要识别它们。 That way you can use them in your replacement string.
这样您就可以在替换字符串中使用它们。 For example:
例如:
var pattern = @"(-)(\d+)(-)";
var replaced = Regex.Replace(text, pattern, "$1AA$3");
or using a MatchEvaluator:或使用 MatchEvaluator:
var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value + "AA" + m.Groups[3].Value);
Another way, slightly messy, could be using a lookbehind/lookahead:另一种稍微凌乱的方法是使用后视/前瞻:
(?<=-)(\\d+)(?=-)
You can do this using lookahead and lookbehind :您可以使用lookahead 和 lookbehind来做到这一点:
var pattern = @"(?<=-)\d+(?=-)";
var replaced = Regex.Replace(text, pattern, "AA");
I also had need for this and I created the following extension method for it:我也需要这个,我为它创建了以下扩展方法:
public static class RegexExtensions
{
public static string ReplaceGroup(
this Regex regex, string input, string groupName, string replacement)
{
return regex.Replace(
input,
m =>
{
var group = m.Groups[groupName];
var sb = new StringBuilder();
var previousCaptureEnd = 0;
foreach (var capture in group.Captures.Cast<Capture>())
{
var currentCaptureEnd =
capture.Index + capture.Length - m.Index;
var currentCaptureLength =
capture.Index - m.Index - previousCaptureEnd;
sb.Append(
m.Value.Substring(
previousCaptureEnd, currentCaptureLength));
sb.Append(replacement);
previousCaptureEnd = currentCaptureEnd;
}
sb.Append(m.Value.Substring(previousCaptureEnd));
return sb.ToString();
});
}
}
Usage:用法:
var input = @"[assembly: AssemblyFileVersion(""2.0.3.0"")][assembly: AssemblyFileVersion(""2.0.3.0"")]";
var regex = new Regex(@"AssemblyFileVersion\(""(?<version>(\d+\.?){4})""\)");
var result = regex.ReplaceGroup(input , "version", "1.2.3");
Result:结果:
[assembly: AssemblyFileVersion("1.2.3")][assembly: AssemblyFileVersion("1.2.3")]
If you don't want to change your pattern you can use the Group Index and Length properties of a matched group.如果您不想更改您的模式,您可以使用匹配组的组索引和长度属性。
var text = "example-123-example";
var pattern = @"-(\d+)-";
var regex = new RegEx(pattern);
var match = regex.Match(text);
var firstPart = text.Substring(0,match.Groups[1].Index);
var secondPart = text.Substring(match.Groups[1].Index + match.Groups[1].Length);
var fullReplace = firstPart + "AA" + secondPart;
Here is another nice clean option that does not require changing your pattern.这是另一个不错的清洁选项,不需要更改您的模式。
var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, (_match) =>
{
Group group = _match.Groups[1];
string replace = "AA";
return String.Format("{0}{1}{2}", _match.Value.Substring(0, group.Index - _match.Index), replace, _match.Value.Substring(group.Index - _match.Index + group.Length));
});
go through the below coding to get the separate group replacement.通过下面的编码来获得单独的组替换。
new_bib = Regex.Replace(new_bib, @"(?s)(\\bibitem\[[^\]]+\]\{" + pat4 + @"\})[\s\n\v]*([\\\{\}a-zA-Z\.\s\,\;\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']{20,70})", delegate(Match mts)
{
var fg = mts.Groups[0].Value.ToString();
var fs = mts.Groups[1].Value.ToString();
var fss = mts.Groups[2].Value.ToString();
fss = Regex.Replace(fss, @"[\\\{\}\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\\" + dblqt + @"\\\;\\\`\\\']+", "");
return "<augroup>" + fss + "</augroup>" + fs;
}, RegexOptions.IgnoreCase);
Here is a version similar to Daniel's but replacing multiple matches:这是一个类似于 Daniel 的版本,但替换了多个匹配项:
public static string ReplaceGroup(string input, string pattern, RegexOptions options, string groupName, string replacement)
{
Match match;
while ((match = Regex.Match(input, pattern, options)).Success)
{
var group = match.Groups[groupName];
var sb = new StringBuilder();
// Anything before the match
if (match.Index > 0)
sb.Append(input.Substring(0, match.Index));
// The match itself
var startIndex = group.Index - match.Index;
var length = group.Length;
var original = match.Value;
var prior = original.Substring(0, startIndex);
var trailing = original.Substring(startIndex + length);
sb.Append(prior);
sb.Append(replacement);
sb.Append(trailing);
// Anything after the match
if (match.Index + match.Length < input.Length)
sb.Append(input.Substring(match.Index + match.Length));
input = sb.ToString();
}
return input;
Replace code:替换代码:
var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.ReplaceGroupValue(text, pattern, 1, "AA");
Extension class:扩展类:
public static class RegexExtensions
{
[Pure]
public static string ReplaceGroupValue(this Regex source, string input, string groupName, string destinationValue)
{
return ReplaceGroupValue(
source,
input,
m => m.Groups[groupName],
p => destinationValue);
}
[Pure]
public static string ReplaceGroupValue(this Regex source, string input, int groupIdx, string destinationValue)
{
return ReplaceGroupValue(
source,
input,
m => m.Groups[groupIdx],
p => destinationValue);
}
[Pure]
public static string ReplaceGroupValue(this Regex source, string input, string groupName, Func<string, string> destinationValueSelector)
{
return ReplaceGroupValue(
source,
input,
m => m.Groups[groupName],
destinationValueSelector);
}
[Pure]
public static string ReplaceGroupValue(this Regex source, string input, int groupIdx, Func<string, string> destinationValueSelector)
{
return ReplaceGroupValue(
source,
input,
m => m.Groups[groupIdx],
destinationValueSelector);
}
[Pure]
private static string ReplaceGroupValue(
Regex source,
string input,
Func<Match, Group> groupSelector,
Func<string, string> destinationValueSelector)
{
var matchResult = source.Matches(input);
if (matchResult.Count <= 0)
{
return input;
}
var text = input;
foreach (var group in matchResult.OfType<Match>().Select(groupSelector).OrderByDescending(p => p.Index))
{
var begin = group.Index > 0 ? text.Substring(0, group.Index) : string.Empty;
var end = group.Index + group.Length < text.Length
? text.Substring(group.Index + group.Length)
: string.Empty;
var destinationValue = destinationValueSelector.Invoke(group.Value);
text = $"{begin}{destinationValue}{end}";
}
return text;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.