C# 替换C中的正则表达式字符串#
我有一个C# 替换C中的正则表达式字符串#,c#,replace,expression,C#,Replace,Expression,我有一个Regexrule.cs类,它由以下属性组成: public string Expression { get; set; } public string FirstOpen { get; set; } public string FirstClose { get; set; } public string SecondOpen { get; set; } public string SecondClose { get; set; } Expres
Regexrule.cs
类,它由以下属性组成:
public string Expression { get; set; }
public string FirstOpen { get; set; }
public string FirstClose { get; set; }
public string SecondOpen { get; set; }
public string SecondClose { get; set; }
Expression
保存一个正则表达式值,并且它总是要返回两个组
这四个字段(不包括表达式
)是预期找到的两个组的前缀和后缀。。。因此,这种情况发生了:
FirstOpen+Group[1]+FirstClose
和SecondOpen+Group[2]+SecondClose
无论如何,我有一个列表规则包含RegexRules
对象列表的code>
困境
我的目标是循环遍历每一个(RegexRules r
),在一个特别长的字符串上运行其各自的表达式(r.expression
),当找到两个预期的组时,我希望脚本以所示的方式用前缀和后缀封装每个组
r.FirstOpen+Group[1]+r.FirstClose
和r.SecondOpen+Group[2]+r.SecondClose
我尝试了许多不同的方法,但有一件事我知道,str.Replace
在循环中不起作用。因为它会对表达式结果的每次出现反复应用前缀和后缀
那么,还有什么其他方法可以实现这一点呢
多谢各位
编辑
这是我目前得到的:
foreach (RegexRule r in RegexRules.ToList())
{
Regex rx = new Regex(r.Expression);
MatchCollection mc = rx.Matches(str);
foreach (Match m in mc)
{
MessageBox.Show("replacing");
str = str.Replace(m.Groups[1].Value, r.OpenBBOne + m.Groups[1].Value + r.CloseBBOne);
}
}
编辑2-细节
用户将在.config
文件中创建自己的正则表达式配置,格式如下:
reg{(\w+)(\w+)\(\);}=[(“前缀X1”,“后缀X1”),(“前缀X2”,“后缀X2”)代码>
reg
-定义新RegexRule的标准单词
{{(\w+(\w+)(\);}
-它们的正则表达式(条件:表达式在其匹配项中必须始终返回2个组)
[(“前缀x1”、“后缀x1”),(“前缀x2”、“后缀x2”)]
“[(”“,”“),(”“,”“)]中的两个参数-表示两个组的前缀和后缀
**范例**
如果我们将上述配置应用于此字符串:
Lorem ipsum foo.bar();dolor sit bar.foo();amit concetetEUR…
正则表达式将捕获foo.bar()
作为匹配,根据正则表达式,foo
是匹配[1]组[1],而bar
是匹配[1]组[2]
这同样适用于bar.foo()
,因为bar
是匹配[2]组[1],而foo
match[2]组[2]
我希望这是有意义的…根据我们的讨论,我认为这可能是您的解决方案。这与我所做的第一个评论有关。它使用.Distinct()
为您的匹配集合提供了唯一的值,这样您就不会将前缀和后缀组合在一起
foreach(RegexRule r in RegexRules.ToList())
{
Regex rx = new Regex(r.Expression);
MatchCollection mc = rx.Matches(str);
foreach(Match m in mc.OfType<Match>().Distinct())
{
MessageBox.Show("replacing");
str = str.Replace(m.Groups[1].Value,
r.OpenBBOne + m.Groups[1].Value + r.CloseBBOne);
}
}
foreach(RegexRules.ToList()中的RegexRule r)
{
正则表达式rx=新正则表达式(r.Expression);
MatchCollection mc=rx.Matches(str);
foreach(在mc.OfType().Distinct()中匹配m)
{
MessageBox.Show(“替换”);
str=str.Replace(m.Groups[1]。值,
r、 OpenBBOne+m.Groups[1].Value+r.CloseBBOne);
}
}
如果出于某种原因不能使用LINQ,您可以自己创建一个新的列表
,只添加列表中尚未包含的内容,从而基本上完成相同的工作
foreach(RegexRule r in RegexRules.ToList())
{
Regex rx = new Regex(r.Expression);
MatchCollection mc = rx.Matches(str);
List<Match> matches = new List<Match>();
List<string> strings = new List<string>();
foreach(Match m in mc)
if(!strings.Contains(m.Value))
{
matches.Add(m);
strings.Add(m.Value);
}
foreach(Match m in matches)
{
MessageBox.Show("replacing");
str = str.Replace(m.Groups[1].Value,
r.OpenBBOne + m.Groups[1].Value + r.CloseBBOne);
}
}
foreach(RegexRules.ToList()中的RegexRule r)
{
正则表达式rx=新正则表达式(r.Expression);
MatchCollection mc=rx.Matches(str);
列表匹配项=新列表();
列表字符串=新列表();
foreach(在mc中匹配m)
如果(!strings.Contains(m.Value))
{
添加(m);
字符串。添加(m.Value);
}
foreach(匹配中的匹配m)
{
MessageBox.Show(“替换”);
str=str.Replace(m.Groups[1]。值,
r、 OpenBBOne+m.Groups[1].Value+r.CloseBBOne);
}
}
这真的让人觉得你在试图强制一个不符合实际需要的设计模式。你可能想后退一步,试着从不同的角度看你在做什么。My$。02@JeremyHolovacs我不知道……还能怎么做?@BarryD,假设你有([0-9])([a-z])
作为正则表达式和1aa1
作为输入字符串。您是希望两个1
s都被替换,还是只想替换第一个(即与正则表达式匹配的一个)?@BarryD。我不确定,我不知道您试图用这种方法来满足什么需求。但通常当我看到人们在使用高度灵活的代码(如正则表达式)时试图围绕它来包装结构,这是一个在设计上走错了路的案例。问题通常是你试图做一些你不需要做的事情。至于在这种情况下,我没有任何有价值的东西可以提供。只是要小心,你的技术实现实际上解决了一个业务问题这不是你自己造成的问题。你的列表
不能有唯一的值有什么原因吗?如果它能够有唯一的值,这会不会解决你的问题,并且你可以使用string.Replace()
?你能提供一个你使用的输入和你得到的不正确输出的示例吗?这不仅很难解释,而且我真的无法理解,你提出了我唯一的解决方案,毫无例外。它奏效了。非常感谢你,先生!!但是:mc.Distinct();
不起作用,因为它是一个匹配集合
,谢谢你的选择:)啊,是的,你是对的。我忘了你必须定义类型才能获得枚举数。我已经编辑了我的答案,所以它应该适用于LINQ。