在正则表达式中嵌套OR

时间:2013-01-29 12:34:08

标签: javascript regex perl boost-regex boost-xpressive

如何匹配我需要执行另一组or的表达式?

即,如何匹配格式

[
  [
    [ a | b ] |
    [ x | y ]
  ]
]

其中a,b,x和y是字符串。

我想匹配像

这样的短语
a
b
x
y
a x
a y
b x
b y
x a
x b
y a
y b

但不是那些:

a b
x y
z z 

我试图在 Boost Xpressive 中使用它,所以我可以选择使用ECMAScript或Perl类型的正则表达式。

4 个答案:

答案 0 :(得分:4)

你可以这样做:

[ab] [xy]|[xy] [ab]|[abxy]

这里有3种选择:

  • 仅限abxy(单个字符)
  • 或2个字符,ab位于xy之前,其间为空格。
  • 或2个字符,xy位于ab之前,其间为空格。

我把[abxy]放在后面,以防万一你搜索时,它会搜索前面的那些(配对的),然后再搜索单个。如果使用正则表达式进行搜索,顺序很重要,但在进行验证时,这并不重要。

另一种写作方式:

[ab]( [xy])?|[xy]( [ab])?

这只适用于角色,但你可以使它适用于字符串。例如,假设您有4个字符串s1s2s3s4

(s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?

搜索:

  • s1s2,可能是也可能不是(0或1个实例),后跟s3s4
  • (反过来说)

这涵盖s1s2等所有案例(单字符串),s2 s3s3 s2等。(配对,可以撤消订单)。由于量词的默认 greedy 属性,上面的正则表达式将在求助于单个字符串之前搜索更长的版本(配对)。

请注意,我在上面的正则表达式中使用捕获组 (pattern),它将记录与pattern内部匹配的字符串的位置。如果您不需要引用与模式匹配的文本,则可以将它们设为非捕获组(?:pattern)。这样可以节省一些时钟周期。

(?:s1|s2)(?: (?:s3|s4))?|(?:s3|s4)(?: (?:s1|s2))?

(我将捕获组更改为非捕获组的任务留给另一个正则表达式作为练习。它就像添加?:一样简单)

正在搜索或验证?

如果你想找到这样的模式,那么上面的正则表达式应该适合你。

如果要验证字符串是否与模式匹配,则需要使用锚点^(匹配字符串的开头),$(匹配字符串的结尾)以确保字符串遵循确切的格式:

^([ab] [xy]|[xy] [ab]|[abxy])$
^([ab]( [xy])?|[xy]( [ab])?)$
^((s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?)$
^(?:(?:s1|s2)(?: (?:s3|s4))?|(?:s3|s4)(?: (?:s1|s2))?)$

请注意,我使用()捕获组)包围上述部分中的正则表达式,但实际上我只需要分组。这是因为我内部有一个替换|

可扩展性和限制

  • 您可以根据需要向第一组或第二组添加更多字符串:

    ^([abcd]( [xyz])?|[xyz]( [abcd])?)$
    
  • 但是,如果你想增加组的数量,我建议你用空格分割字符串并循环遍历标记以找到组的排列,而不是使用正则表达式。

    < / LI>

答案 1 :(得分:1)

如果不在正则表达式中重复abxy,就没有一种方便的方法可以做到这一点,但这个问题可以通过以下方式解决:从预先声明的子表达式构建表达式。

此代码演示。请注意,DATA的前三行无效,并且不会在输出中再现。

use v5.10;
use warnings;

my $ab = qr/a|b/;
my $xy = qr/x|y/;

my $re = qr/^
(?:
  $ab (?: \s+ $xy)? | $xy (?: \s+ $ab)?
)
$/x;

while (<DATA>) {
  print if /$re/;
}


__DATA__
a b
x y
z z
a
b
x
y
a x
a y
b x
b y
x a
x b
y a 
y b

<强>输出

a
b
x
y
a x
a y
b x
b y
x a
x b
y b

答案 2 :(得分:0)

试试这个:

^((a|b)( x| y)?|(x|y)( a| b)?)$

正则表达式剖析:

# ^            - Line start
# (            - Group start
# (a|b)( x| y) - Match A or B followed by X or Y
# ?            - Where (X|Y) is optional
# |            - Or
# (x|y)( a| b) - Match X or Y followed by A or B
# ?            - Where (A|B) is optional
# )            - And group
# $            - End of line.

匹配:

a    y
b    a x
x    y b

但不是:

a b
x y
z z

答案 3 :(得分:0)

简单:

(a|b|x|y|((a|b) (x|y))|((x|y) (a|b)))