如何匹配我需要执行另一组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类型的正则表达式。
答案 0 :(得分:4)
你可以这样做:
[ab] [xy]|[xy] [ab]|[abxy]
这里有3种选择:
a
,b
,x
,y
(单个字符)a
或b
位于x
或y
之前,其间为空格。x
或y
位于a
或b
之前,其间为空格。我把[abxy]
放在后面,以防万一你搜索时,它会搜索前面的那些(配对的),然后再搜索单个。如果使用正则表达式进行搜索,顺序很重要,但在进行验证时,这并不重要。
另一种写作方式:
[ab]( [xy])?|[xy]( [ab])?
这只适用于角色,但你可以使它适用于字符串。例如,假设您有4个字符串s1
,s2
,s3
,s4
:
(s1|s2)( (s3|s4))?|(s3|s4)( (s1|s2))?
搜索:
s1
或s2
,可能是也可能不是(0或1个实例),后跟s3
或s4
这涵盖s1
,s2
等所有案例(单字符串),s2 s3
,s3 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)
如果不在正则表达式中重复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
答案 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)))