Regex 试着学着向前看和向后看
我已经设置了一个简单的测试来测试URL中a/后面的单词“Home”。我有它的工作没有看aheads/落后,但想用这些做同样的事情Regex 试着学着向前看和向后看,regex,perl,Regex,Perl,我已经设置了一个简单的测试来测试URL中a/后面的单词“Home”。我有它的工作没有看aheads/落后,但想用这些做同样的事情 my $page = "/Home"; #should 'match' #or $page = "/New Homes"; #should 'no match' #A if ($page =~ /Home | Home/) { print "no match A"; } else { print "match A"; } print "\n\n";
my $page = "/Home"; #should 'match'
#or
$page = "/New Homes"; #should 'no match'
#A
if ($page =~ /Home | Home/) {
print "no match A";
} else {
print "match A";
}
print "\n\n";
#B
if ($page =~ /(?<= )Home(?= )/) {
print "no match B";
} else {
print "match B";
}
那么我没有得到什么呢?在您的示例中:
(?<= )Home(?= )
另外,正如注释所示,使用look aheads和look behinds,它们不会作为匹配项返回,它们只是用于查找匹配项。因此,在上面的示例中,Home
将作为匹配项返回,而不是/Home
注意:正如注释中指出的,perl要求对
/
进行转义。我编辑代码以包含转义的/
您的代码让我很困惑,可能您也很困惑
这个
相当于
my $page = '/New Homes';
因为不需要在文本字符串中转义斜杠,也不需要使用双引号,除非需要插入变量
还有这个
if ($page =~ /Home | Home/) {
print "no match A";
} else {
print "match A";
}
当存在匹配项时,正在打印不匹配A
,反之亦然,因此不匹配A
的输出是正确的,因为的“主页”
确实出现在$page
中
你担心的情况
if ($page =~ /(?<= )Home(?= )/) {
print "no match B";
} else {
print "match B";
}
输出
match A
no match B
我不知道你为什么认为这两种模式是等价的
/(?<= )Home(?= )/
不包括匹配中的空格,以及
/Home(?= )|(?<= )Home/
不包括匹配中的空格
您可能想要:
m{(?<![^/])Home(?![^/])}
m{(?)?
类似于
m{(?<=/)Home(?=/)}
m{(?![^/])
在字符串末尾也匹配。您可能应该转义/
或者注意应该使用不同的分隔符。除非它与perl有关,/
不在需要转义的列表中。它与perl有关,因为(正如您在OP的代码中看到的)默认情况下,正则表达式文字使用斜杠分隔。因此,如果不转义斜杠,它将结束正则表达式。请选择其他分隔符或转义斜杠;)我希望你的程序顶部有use strict
和use warnings
?我觉得你的#A匹配是向后的。它是/Home | Home/
,它在“Home”之前或之后用空格匹配。然后,你的if语句打印“no match A”如果有匹配项。我想你希望你的正则表达式像/Home\/\124;\/Home/
(或者更改分隔符像m!Home/\124;/Home!
)那样,并将你的if/else换成另一种方式。你的#B if语句也是这样做的(但见Nick的答案)。
/(?<= )Home(?= )/
/ Home /
/Home(?= )|(?<= )Home/
/Home | Home/
m{(?<![^/])Home(?![^/])}
m{(?<=/)Home(?=/)}