2

我设置了一个简单的测试来测试 URL 中 / 之后的单词“Home”。我让它在没有前瞻/后视的情况下工作,但想用它们来做同样的事情。

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";
}

回报:

no match A
match B #incorrect

那么我没有得到什么?

4

3 回答 3

2

在您的示例中:

(?<= )Home(?= )

您在这里所做的是在 home 之前和之后搜索空白空间(或空白)。您想将搜索字符串放在括号内。要搜索/之前home使用这个:

(?<=\/)Home

另外,就像一个注释一样,使用前瞻和后瞻,它们不会作为匹配返回,它们只是用于查找匹配。因此,在上面的示例中,Home将作为匹配项返回,而不是/Home.

注意:正如评论中指出的那样,perl 需要/转义。我编辑了代码以包含一个转义的/.

于 2012-12-07T21:43:19.107 回答
1

我不知道你为什么认为这两种模式是等价的。

/(?<= )Home(?= )/

匹配相同的字符串

/ Home /

不包括匹配中的空格,并且

/Home(?= )|(?<= )Home/

匹配相同的字符串

/Home | Home/

不包括匹配中的空格。


你可能想要:

m{(?<![^/])Home(?![^/])}

它类似于

m{(?<=/)Home(?=/)}

except(?<![^/])也匹配字符串的开头,(?![^/])也匹配字符串的结尾。

于 2012-12-08T02:14:49.937 回答
0

你的代码让我很困惑,可能你也是。

这个

my $page = "\/Home"; #should 'match'
#or
$page = "\/New Homes"; #should 'no match'

相当于

my $page = '/New Homes';

因为不需要在文字字符串中转义斜杠,也不需要使用双引号,除非您需要插值变量。

还有这个

if ($page =~ /Home | Home/) {
    print "no match A";
} else {
    print "match A";
}

匹配时正在打印no match A,反之亦然,因此您的输出.no match A' Home' $page

您担心的情况

if ($page =~ /(?<= )Home(?= )/) {
    print "no match B";
} else {
    print "match B";
}

有同样的问题,它no match B在匹配时打印。它正在寻找Home, 前面和后面的空格。$page包含前面'/New Homes''Home'空格,但后面没有空格。所以它说match B因为没有匹配。

试试你的程序的这个变体,纠正 and 的感觉matchno match添加use strictand use warnings

use strict;
use warnings;

my $page = '/New Homes';

if ($page =~ /Home | Home/) {
  print 'match A';
}
else {
  print 'no match A';
}

print "\n\n";

if ($page =~ /(?<= )Home(?= )/) {
  print 'match B';
}
else {
  print 'no match B';
}

输出

match A

no match B
于 2012-12-07T23:31:29.317 回答