Regex:以不同的顺序匹配组,而不重复组

qyyhg6bp  于 2023-08-08  发布在  其他
关注(0)|答案(4)|浏览(91)

假设我有两个这样的字符串:

XABY
XBAY

字符串
一个简单的正则表达式匹配两者会像这样:

X(AB|BA)Y


然而,我有一个例子,其中A和B是复杂的字符串,我正在寻找一种方法来避免必须指定两次(在|)。有没有一种方法可以做到这一点(这大概比必须指定两次更简单)?
谢啦,谢啦

0wi1tuuw

0wi1tuuw1#

X(?:A()|B()){2}\1\2Y

字符串
基本上,您使用一个空的捕获组在匹配时检查每个项,然后反向引用确保所有内容都已检查。
请注意,这依赖于未记录的正则表达式行为,因此不能保证它在您的正则表达式风格中工作-如果它工作,也不能保证它将随着该风格的发展而继续工作。但据我所知,它适用于所有支持反向引用的风格。(编辑:它在JavaScript中不起作用。

**编辑:**你说你使用命名组来捕获匹配的部分,这给正则表达式增加了很多视觉混乱,如果不是真实的的复杂性。好吧,如果你碰巧使用.NET正则表达式,你仍然可以使用简单的编号组作为“复选框”。下面是一个简单的例子,它在不知道内部顺序的情况下查找并挑选一堆month-day字符串:

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"]);
}


这是因为在.NET中,命名组的存在对非命名组的顺序没有影响。命名组有编号,但这些编号从最后一个未命名组之后开始。(我知道这看起来很复杂,但这样做有很好的理由。
通常情况下,您希望避免同时使用命名和非命名捕获组,特别是在使用反向引用时,但我认为这种情况可能是一个合理的例外。

ny6fqffe

ny6fqffe2#

你可以将regex片段存储在变量中,并执行以下操作:

A=/* relevant regex pattern */
B=/* other regex pattern */
regex = X($A$B|$B$A)Y

字符串
通过这种方式,您只需在每个正则表达式的行中指定一次,这将使其更易于维护。
旁注:你试图找到排列,这是可以的,因为你只看2个子正则表达式。但是如果您想添加第三个(或第四个),您的正则表达式排列将急剧增长-(abc|亚洲银行|巴克|bca|驾驶室|CBA)-或者更糟。如果你需要沿着排列的道路走下去,在stackoverflow上有一些很好的讨论。它用于字母排列,解决方案使用awk/bash/perl,但这至少给了您一个起点。

nxagd54h

nxagd54h3#

试试这个

X((A|B){2})Y

字符串

eqzww0vc

eqzww0vc4#

如果有几个字符串,其中包含任何类型的字符,你会更好地使用:

X(.)+Y

字符串
只有数字

X([0-9])+Y


只有信

X([a-zA-Z])+Y


字母和数字

X([a-zA-Z][0-9])+Y

相关问题