为啥替代品的顺序在正则表达式中很重要?
Posted
技术标签:
【中文标题】为啥替代品的顺序在正则表达式中很重要?【英文标题】:Why does the order of alternatives matter in regex?为什么替代品的顺序在正则表达式中很重要? 【发布时间】:2013-08-03 18:27:59 【问题描述】:代码
using System;
using System.Text.RegularExpressions;
namespace RegexNoMatch
class Program
static void Main ()
string input = "a foobar& b";
string regex1 = "(foobar|foo)&?";
string regex2 = "(foo|foobar)&?";
string replace = "$1";
Console.WriteLine(Regex.Replace(input, regex1, replace));
Console.WriteLine(Regex.Replace(input, regex2, replace));
Console.ReadKey();
预期输出
a foobar b
a foobar b
实际输出
a foobar b
a foobar& b
问题
当正则表达式模式中“foo”和“foobar”的顺序改变时,为什么替换不起作用?如何解决这个问题?
【问题讨论】:
【参考方案1】:正则表达式引擎尝试按照指定的顺序匹配替代项。因此,当模式为 (foo|foobar)&?
时,它会立即匹配 foo
并继续尝试查找匹配项。输入字符串的下一位是bar& b
,无法匹配。
换句话说,因为foo
是foobar
的一部分,所以(foo|foobar)
永远不会匹配foobar
,因为它总是首先匹配foo
。
实际上,有时这可能是一个非常有用的技巧。 (o|a|(\w))
模式将允许您以不同的方式捕获 \w
和 a
或 o
:
Regex.Replace("a foobar& b", "(o|a|(\\w))", "$2") // fbr& b
【讨论】:
为什么正则表达式不贪心?我认为它应该匹配它可以匹配的最长字符串。 @Athari greediness 适用于量词,而不适用于交替。 有没有办法强迫对交替的贪婪,或者我必须按字母倒序对交替进行排序? @Athari 字母顺序没有区别。交替应首先按 broadest 模式排序,例如foobar
比foo
更广泛,因为任何匹配foo
的字符串也将匹配foobar
(当然foo(bar)?
在这里更明智)。除非您尝试使用我更新的答案中描述的技巧。
在我的真实案例中,这个列表很长,所以让正则表达式变得更复杂是不值得的。我想this suggestion 解决了我的问题,因为我需要匹配单独的单词。以上是关于为啥替代品的顺序在正则表达式中很重要?的主要内容,如果未能解决你的问题,请参考以下文章
用正则表达式不就可以让用户名不能包含一些字符了吗,为啥还要转义