如何匹配我需要做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 类型的正则表达式。
如何匹配我需要做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 类型的正则表达式。
你可以这样做:
[ab] [xy]|[xy] [ab]|[abxy]
这里有3个选择:
a
, b
, x
, y
(单个字符)a
或b
在x
or之前y
,中间有空格。x
或y
在a
or之前b
,中间有空格。我放在[abxy]
后面,以防万一你搜索时,它会先搜索前面的(配对的),然后再搜索单个的。如果您使用正则表达式进行搜索,顺序很重要,但在您进行验证时并不重要。
另一种写法:
[ab]( [xy])?|[xy]( [ab])?
这仅适用于字符,但您可以使其适用于字符串。例如,假设您有 4 个字符串s1
, s2
, s3
, s4
:
(s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?
它搜索:
s1
要么s2
,要么 (0 或 1 个实例),后跟s3
ors4
这涵盖了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])?)$
但是,如果你想增加组的数量,我建议你用空格分割字符串并循环通过标记来找到组的排列,而不是使用正则表达式。
没有在正则表达式中重复a
,和的简便方法可以做到这一点b
,但是可以通过从预先声明的子表达式构建表达式来缓解这个问题。x
y
此代码演示。请注意,前三行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
试试这个:
^((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
简单的:
(a|b|x|y|((a|b) (x|y))|((x|y) (a|b)))