C# 高级regex.replace处理
我正在使用带有MatchEvaluator委托的正则表达式来处理格式字符串,例如,“时间:%t,字节:%b”将用时间戳替换“%t”,用字节计数替换“%b”。不用说,还有很多其他的选择 为此,我使用:C# 高级regex.replace处理,c#,regex,C#,Regex,我正在使用带有MatchEvaluator委托的正则表达式来处理格式字符串,例如,“时间:%t,字节:%b”将用时间戳替换“%t”,用字节计数替换“%b”。不用说,还有很多其他的选择 为此,我使用: Regex regex = new Regex("%((?<BytesCompleted>b)|(?<BytesRemaining>B)|(?<TimeStamp>t))"); string s = "%bhello%t(HH:MM:SS)%P";
Regex regex = new Regex("%((?<BytesCompleted>b)|(?<BytesRemaining>B)|(?<TimeStamp>t))");
string s = "%bhello%t(HH:MM:SS)%P";
string r = regex.Replace(s, new MatchEvaluator(ReplaceMatch));
如果我可以在委托中使用正则表达式组名(甚至数字,我不是那么挑剔),而不是与原始匹配进行比较,以找出这是哪一个匹配,那就更好了:
string ReplaceMatch(Match m)
{
...
case "%t":
...
case "%b";
...
}
它相当丑陋;我想用
string ReplaceMatch(Match m)
{
...
case "BytesCompleted":
...
case "TimeStamp":
...
}
通过调试器或谷歌,我看不到任何明显的东西。有什么想法吗 如果能够在交换机中使用组名就好了;不幸的是,
组
对象没有名称
属性(其基类也没有捕获
),因此您最好能做到以下几点:
string ReplaceMatch(Match m)
{
if (m.Groups["BytesCompleted"].Success) // ...
else if (m.Groups["BytesRemaining"].Success) // ...
// ...
}
您可以使用
Regex.GroupNameFromNumber
实例方法,不幸的是,这意味着匹配计算器方法需要引用Regex
对象:
string ReplaceMatch(Match m)
{
for (int i = 0; i < m.Groups.Count; i++)
{
string groupName = _regex.GroupNameFromNumber(i);
switch (groupName)
{
case "BytesCompleted":
// do something
break;
case "BytesRemaining":
// do somehting else
break;
...
}
}
...
}
字符串替换匹配(匹配m)
{
对于(int i=0;i
这里我假设
Regex
对象可以通过\u Regex
变量访问。我们需要结合Sina和james的答案。我们需要枚举组以获得索引并检查组是否成功。然后我们使用索引来获取组名。我已经扩展到一个自我解释测试,它使用字典替换匹配的子字符串。如果框架中对组名的支持再多一点,这就容易多了
另请参阅另一个可能适合您的答案:
[测试]
public void ExploreRxReplace()
{
var txt=“ABC XYZ DEF”;
var exp=“***XYZ xxx”;
var rx=new Regex(@“\s*(?ABC)\s*|\s*(?DEF)\s*”);
var data=newdictionary(){{“abc”,“***”},{“def”,“xxx”};
变量txt2=rx.Replace(txt,(m)=>
{
var sb=新的StringBuilder();
var pos=m.指数;
对于(var idx=1;idx
string ReplaceMatch(Match m)
{
for (int i = 0; i < m.Groups.Count; i++)
{
string groupName = _regex.GroupNameFromNumber(i);
switch (groupName)
{
case "BytesCompleted":
// do something
break;
case "BytesRemaining":
// do somehting else
break;
...
}
}
...
}
[Test]
public void ExploreRxReplace()
{
var txt = " ABC XYZ DEF ";
var exp = " *** XYZ xxx ";
var rx = new Regex(@"\s*(?<abc>ABC)\s*|\s*(?<def>DEF)\s*");
var data = new Dictionary<string, string>() { { "abc", "***" }, { "def", "xxx" } };
var txt2 = rx.Replace(txt, (m) =>
{
var sb = new StringBuilder();
var pos = m.Index;
for (var idx = 1; idx < m.Groups.Count; idx++)
{
var group = m.Groups[idx];
if (!group.Success)
{
// ignore non-matching group
continue;
}
var name = rx.GroupNameFromNumber(idx);
// append what's before
sb.Append(txt.Substring(pos, group.Index - pos));
string value = null;
if (group.Success && data.TryGetValue(name, out value))
{
// append dictionary value
sb.Append(value);
}
else
{
// append group value
sb.Append(group.Value);
}
pos = group.Index + group.Length;
}
// append what's after
sb.Append(txt.Substring(pos, m.Index + m.Length - pos));
return sb.ToString();
});
Assert.AreEqual(exp, txt2);
}