-1

如何匹配我需要做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

4 回答 4

4

你可以这样做:

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

这里有3个选择:

  • 只有a, b, x, y(单个字符)
  • 或 2 个字符,abxor之前y,中间有空格。
  • 或 2 个字符,xyaor之前b,中间有空格。

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

另一种写法:

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

这仅适用于字符,但您可以使其适用于字符串。例如,假设您有 4 个字符串s1, s2, s3, s4

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

它搜索:

  • 要么,要么 ,要么 ,s1要么s2,要么 (0 或 1 个实例),后跟s3ors4
  • (另一种方式)

这涵盖了s1,s2等(单个字符串)、s2 s3,s3 s2等(配对,可以颠倒顺序)的所有情况。由于量词的默认贪婪属性,上面的正则表达式将在使用单个字符串之前搜索更长的版本(配对) 。

请注意,我在上面的正则表达式中使用了捕获组 (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])?)$
    
  • 但是,如果你想增加组的数量,我建议你用空格分割字符串并循环通过标记来找到组的排列,而不是使用正则表达式。

于 2013-01-29T12:42:24.730 回答
1

没有在正则表达式中重复a,和的简便方法可以做到这一点b,但是可以通过从预先声明的子表达式构建表达式来缓解这个问题。xy

此代码演示。请注意,前三行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
于 2013-01-29T13:03:49.663 回答
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
于 2013-01-29T12:36:37.563 回答
0

简单的:

(a|b|x|y|((a|b) (x|y))|((x|y) (a|b)))
于 2013-01-29T12:49:31.237 回答