假设我有两个这样的字符串:
XABY
XBAY
Run Code Online (Sandbox Code Playgroud)
一个匹配两者的简单正则表达式将如下所示:
X(AB|BA)Y
Run Code Online (Sandbox Code Playgroud)
但是,我有一个案例,其中A和B是复杂的字符串,我正在寻找一种方法来避免必须指定它们两次(在|的每一侧).有没有办法做到这一点(可能比指定它们两次更简单)?
谢谢
Ala*_*ore 22
X(?:A()|B()){2}\1\2Y
Run Code Online (Sandbox Code Playgroud)
基本上,您使用空捕获组在匹配时检查每个项目,然后反向引用确保已检查所有项目.
请注意,这依赖于未记录的正则表达式行为,因此无法保证它在您的正则表达式中起作用 - 如果确实如此,则无法保证它会随着该风格的发展而继续工作.但据我所知,它适用于支持反向引用的每种风格.(编辑:它在JavaScript中不起作用.)
编辑:你说你正在使用命名组捕获匹配的部分,这给正则表达式增加了很多视觉混乱,如果不是真正的复杂性.好吧,如果你碰巧使用.NET正则表达式,你仍然可以使用简单的编号组作为"复选框".这是一个简单的例子,它可以在不知道内部顺序的情况下查找和挑选一堆月日字符串:
Regex r = new Regex(
@"(?:
(?<MONTH>Jan|Feb|Mar|Apr|May|Jun|Jul|Sep|Oct|Nov|Dec)()
|
(?<DAY>\d+)()
){2}
\1\2",
RegexOptions.IgnorePatternWhitespace);
string input = @"30Jan Feb12 Mar23 4Apr May09 11Jun";
foreach (Match m in r.Matches(input))
{
Console.WriteLine("{0} {1}", m.Groups["MONTH"], m.Groups["DAY"]);
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为在.NET中,命名组的存在对非命名组的排序没有影响.命名组具有分配给它们的编号,但这些编号在最后一个非命名组之后开始.(我知道这看起来很复杂,但有充分的理由这样做.)
通常,您希望避免将命名和非命名捕获组一起使用,尤其是在使用反向引用时,但我认为这种情况可能是合法的异常.
您可以将regex片段存储在变量中,并执行以下操作:
A=/* relevant regex pattern */
B=/* other regex pattern */
regex = X($A$B|$B$A)Y
Run Code Online (Sandbox Code Playgroud)
这样,您只需在自己的行上指定一次正则表达式,这样可以更容易维护.
旁注:你试图找到排列,这是好的,因为你只看了2个子目标.但是如果你想增加第三个(或第四个),你的正则表达式排列会急剧增长 - (abc | acb | bac | bca | cab | cba) - 或者更糟.如果你需要走下排列的道路,那么在stackoverflow上有一些很好的讨论.它用于字母排列,解决方案使用awk/bash/perl,但这至少为你提供了一个起点.
| 归档时间: |
|
| 查看次数: |
15729 次 |
| 最近记录: |