有没有办法计算Regex.Replace调用的替换次数?
E.g。对于Regex.Replace("aaa", "a", "b");
我希望得到数字3(结果为"bbb"
);对于Regex.Replace("aaa", "(?<test>aa?)", "${test}b");
我希望得到数字2(结果为"aabab"
)。
我能想到这样做的方式:
方法1和2需要手动解析$替换,方法3需要正则表达式匹配字符串两次。有没有更好的方法。
答案 0 :(得分:14)
感谢Chevex和Guffa。我开始寻找更好的方法来获得结果,并发现Match类上有一个Result方法来进行替换。这是拼图中缺失的部分。示例代码如下:
using System.Text.RegularExpressions;
namespace regexrep
{
class Program
{
static int Main(string[] args)
{
string fileText = System.IO.File.ReadAllText(args[0]);
int matchCount = 0;
string newText = Regex.Replace(fileText, args[1],
(match) =>
{
matchCount++;
return match.Result(args[2]);
});
System.IO.File.WriteAllText(args[0], newText);
return matchCount;
}
}
}
如果文件test.txt包含aaa,命令行regexrep test.txt "(?<test>aa?)" ${test}b
会将%errorlevel%设置为2,并将文本更改为aabab。
答案 1 :(得分:7)
您可以使用为每次替换运行的MatchEvaluator
,这样您就可以计算它发生的次数:
int cnt = 0;
string result = Regex.Replace("aaa", "a", m => {
cnt++;
return "b";
});
第二种情况比较棘手,因为你必须产生与替换模式相同的结果:
int cnt = 0;
string result = Regex.Replace("aaa", "(?<test>aa?)", m => {
cnt++;
return m.Groups["test"] + "b";
});
答案 2 :(得分:3)
这应该这样做。
int count = 0;
string text = Regex.Replace(text,
@"(((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)", //Example expression. This one captures URLs.
match =>
{
string replacementValue = String.Format("<a href='{0}'>{0}</a>", match.Value);
count++;
return replacementValue;
});
我不在我的开发计算机上,所以我现在不能这样做,但是我将稍后进行实验,看看是否有办法用lambda表达式而不是声明方法IncrementCount( )只是增加一个int。
编辑以使用lambda表达式而不是声明另一种方法。
EDIT2 如果您事先不知道该模式,您仍然可以获得匹配对象中的所有分组(您引用的$组),因为它们作为GroupCollection包含在内。像这样:
int count = 0;
string text = Regex.Replace(text,
@"(((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)", //Example expression. This one captures URLs.
match =>
{
string replacementValue = String.Format("<a href='{0}'>{0}</a>", match.Value);
count++;
foreach (Group g in match.Groups)
{
g.Value; //Do stuff with g.Value
}
return replacementValue;
});