1

我是 perl 和正则表达式的新手,所以正在lookbehind使用以下代码处理表达式:

my $string = "My hello 12 world 13";

say "$1 $2" if ($string =~ m!(?<=hello\s)(\d+)\s(?<=world\s)(\d+)!);

现在,当我尝试运行上面的代码时,它什么也不打印,但如果我删除了一个后向 expr。它工作正常。

那么,在一个正则表达式中是否不可能有多个向后看,如果是,那么解决方法是什么。

4

2 回答 2

4

您的正则表达式包含这部分:

(\d+)\s(?<=world\s)

这读作:“捕获一系列数字。然后匹配一个空格字符。然后断言当前位置前面是字符串,world后面是空格。”

所以我们正在研究这个:

         \d+   \s
         world \s
My hello 12       world 13

world并且12不匹配;-)

那么在这种情况下为什么不使用普通的正则表达式呢?

m/ hello \s (\d+) \s world \s (\d+) /x

或者使用两个带有后视功能的正则表达式?

$string =~ m / (?<=hello\s) (\d+) /x;
my $x = $1;
$string =~ m / (?<=world\s) (\d+) /x;
my $y = $1;

环视最适合作为一种思维训练练习,或者在搜索和替换操作中排除字符串的某些部分。假设我们想将a owletc 更正为an owl. 我们可以这样做

s/ \b a \s+ ([aeiou]) /an $1/x; # ugly

或向前看:

s/ \b a (?=\s*[aeiou])/an/x; # elegant

使用普通模式匹配,模式通常可以在没有环顾的情况下表达。

于 2012-09-10T14:09:28.637 回答
3

在一个表达式中可以有多个向后查看。

问题是:环顾断言与文本中的某些内容不匹配,因此您的文本中有一个“世界”,但您不匹配它

您只需检查第二个数字系列之前是否有“世界”==>这是不正确的,因此您的正则表达式失败。

你可以做

(?<=hello\s)(\d+)\s\w+\s(?<=world\s)(\d+)

在 Regexr 上查看

regular-expression.info是关于正则表达式的一个很好的信息来源,也许他们对环视的解释可以帮助你理解。

于 2012-09-10T14:10:33.490 回答