计数正则表达式替换(C#)
有没有一种方法可以计算Regex.Replace调用产生的替换次数?计数正则表达式替换(C#)
E.g.对于Regex.Replace("aaa", "a", "b");
我想得到数字3(结果是"bbb"
);对于Regex.Replace("aaa", "(?<test>aa?)", "${test}b");
我想获得数字2(结果是"aabab"
)。
方法,我能想到这样做:
- 使用一个递增捕获变量MatchEvaluator,做更换手动
- 得到一个MatchCollection和重复它,如果用手工更换,并保持一个计数
- 搜索第一,并获得MatchCollection,得到了计数,然后做一个单独更换
方法1和2需要$手工解析取代方法3需要正则表达式匹配字符串两次。有没有更好的办法。
感谢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的文本。
这应该做到这一点。
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。
EDIT修改为使用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;
});
这将工作(谢谢!),但基本上我的方法1。为了使它适用于通用输入和输出,你需要解析替换中的$ {test},所以我们需要更复杂的东西(我指的是“手动解析$替换”)。 – 2011-02-14 16:48:24
匹配对象包含$ groups作为附加到它们的GroupCollection。如果您事先不知道表达式,并且不知道将包括多少个组,那么像我的EDIT2一样循环访问组合集合。我没有在答案中对团队价值做任何事情,但应该很容易让你看到你的成就。 – Chev 2011-02-14 17:04:10
您可以使用,对于每次更换运行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";
});
这是一个简单的命令行工具,可以用任何正则表达式搜索调用,并将模式替换为命令行参数。因此理想的情况是需要一种通用的解决方案,不要提前知道该模式。真的,这是为了兴趣 - 在.Net中做这件事的最好方法是什么?看起来像手动分析$替换的MatchEvaluator方法是前进的方向,但它有点凌乱:( – 2011-02-14 16:50:42
西蒙,看我的编辑。 – Chev 2011-02-14 16:56:36