在单词序列正则表达式中使用贪心方法

时间:2013-06-27 14:54:45

标签: .net regex greedy

我有一个正则表达式,可以转换以下文字

alpha beta + gamma delta - epsilon phi

进入

<ref4> + <ref45> - <ref11>

引用为内部ID。我从以下代码构建正则表达式

EncodeRegex = new Regex("\b(?<nom>" + // word boundary
String.Join("|", Things.Select(t => Regex.Escape(t.Name)).ToArray()) + 
")\b", // word boundary
RegexOptions.IgnoreCase);

上述文字的示例可以是

\b(alpha\ beta|gamma\ delta|epsilon\ phi)\b

其中“alpha beta”和co是我必须识别的文本块。然后,我使用自定义MatchEvaluator替换文本块值及其引用。

我有一个问题;如果我有两个文本块A和B,其中A是B的前缀,则正则表达式取决于A和B的顺序。 只要Alpha被评估,\b(alpha|alpha\ beta)\b就会停止,即使后面是Beta。

除了以递减长度排序文本块之外,还有一种方法可以告诉正则表达式始终与可能的较长文本块匹配吗?


@Anirudh:我使用以下代码

EncodeRegex.Replace(s, new MatchEvaluator(m => Things.Where(Function(r) r.Name.ToUpper() == m.Groups("nom").Value.ToUpper()).Select(Function(r) "<" & r.Reference & ">").FirstOrDefault()))

2 个答案:

答案 0 :(得分:2)

描述

根据您的示例文本,您的组之间存在已知的分隔符,因此您可以简单地使用前瞻来验证分隔符,如下面的表达式中所示,这将阻止较短的前缀完成匹配。

正则表达式:(^|[+-]\s)(alpha|alpha\ beta)(?=\s[+-]|$)

替换为:$1~~~new value~~~

enter image description here

实施例

输入文字

alpha beta + gamma delta - epsilon phi
alpha + alpha beta + gamma delta - epsilon phi

示例代码

Imports System.Text.RegularExpressions
Module Module1
  Sub Main()
    Dim sourcestring as String = "replace with your source string"
    Dim replacementstring as String = "$1~~~new value~~~"
    Dim matchpattern as String = "(^|[+-]\s)(alpha|alpha\ beta)(?=\s[+-]|$)"
    Console.Writeline(regex.Replace(sourcestring,matchpattern,replacementstring,RegexOptions.IgnoreCase OR RegexOptions.Multiline))
  End Sub
End Module

替换后输入

~~~new value~~~ + gamma delta - epsilon phi
~~~new value~~~ + ~~~new value~~~ + gamma delta - epsilon phi

答案 1 :(得分:0)

如果您的模式都不是其他模式的后缀,您可能希望尝试从右到左匹配,有关详细信息,请参阅msdn tutorialreference

另一种方法是从匹配表达式中分解出常见的子表达式,例如

\b(alpha(\ beta)?\b

PS: 再次检查您的代码,因为默认情况下引擎应该贪婪地匹配。