perl regex运算符优先级

时间:2014-07-09 09:07:00

标签: regex perl operator-precedence

我有一个字符串说

my $str = 'click brick trick again';

这是我在这个字符串上尝试的东西

if ($str =~ /((?:[a-z]+ck\s*)+)(\s?again)/){
    print "#$1#$2#\n";
}

打印: #click brick trick #again#
现在我想要2美元起点的空间。但它以1美元的价格被捕获。我应该怎么做才能在$ {1}}中捕获空间,而空格可选。有什么办法吗?是否有允许它的运算符优先级?

3 个答案:

答案 0 :(得分:1)

将单词末尾匹配的可选空格移动到单词的前面:

((?: ?[a-z]+ck)+)( ?again)

答案 1 :(得分:0)

Perl模式匹配(通常)贪婪 - 非贪婪模式匹配在计算上是昂贵的。

然而,我建议摒弃正则表达式,因为听起来你正在尝试做的事情 - 充其量 - 将是一个复杂的RE,这通常不利于可维护性。

然而,您可能想要的(来自perlre):

*?        Match 0 or more times, not greedily
+?        Match 1 or more times, not greedily
??        Match 0 or 1 time, not greedily

答案 2 :(得分:0)

以下是获得所需行为的4种不同方法:

use strict;
use warnings;

my $str = 'click brick trick again';

# Original Regex
print "#$1#$2#\n" if $str =~ /((?:[a-z]+ck\s*)+)(\s?again)/;

# Explicitly specify word followed by optional other words
print "#$1#$2#\n" if $str =~ /([a-z]*ck(?:\s+[a-z]*ck)*)(\s+again)/;

# Force "again" to be preceeded by at least one space using `+` instead of `?`
print "#$1#$2#\n" if $str =~ /((?:[a-z]+ck\s*)+)(\s+again)/;

# No Trailing spaces by using a lookbehind assertion
print "#$1#$2#\n" if $str =~ /((?:[a-z]+ck\s*)+)(?<!\s)(\s+again)/;

# No Leading spaces by using a lookahead assertion
print "#$1#$2#\n" if $str =~ /(?!\s)((?:\s*[a-z]+ck)+)(\s+again)/;

输出:

#click brick trick #again#
#click brick trick# again#
#click brick trick# again#
#click brick trick# again#
#click brick trick# again#