如何从字符串的开头开始使用正则表达式

Jef*_*eff 4 regex perl

这是我遇到的一个古怪的问题(可能以前见过但从未注意过).

这是代码的要点:

my $url = 'http://twitter.com/' . $handle;
my $page = get($url);

if($page =~ m/Web<\/span>\s*<a href=\"(.+?)\"/gi) {
    $website = $1;
}

if($page =~ m/follower_count\" class=\"stats_count numeric\">(.+?)\s*</g) {
    $num_followers = $1;
}
Run Code Online (Sandbox Code Playgroud)

它获得了一个Twitter网址,并使用一些正则表达式来捕获关注者和用户的网站.这段代码实际上运行正常.但是当您在搜索关注者之后切换订单并搜索网站时,网站会显示空白.事实证明,当你正则表达一个字符串时,似乎有点保存最后一个匹配的位置.在html中,网站显示后会显示关注者数量.如果您首先执行跟随者计数正则表达式,就像它启动网站正则表达式,其中跟随者计数停止(如对字符串的索引引用).

令我感到困惑的是,我最后有"g"运算符,表示"全局",如"从全局搜索字符串......".

我在这里错过了什么吗?我似乎无法弄清楚为什么它恢复字符串上的最后一个正则表达式位置(如果这是有道理的).

Phi*_*ter 13

/g标量上下文中的修饰符不会按照您的想法执行.摆脱它.

正如perlretut解释的那样,/g在标量上下文中依次循环每个匹配.它设计用于循环,如下所示:

while ($str =~ /pattern/g) {
    # match on each occurence of 'pattern' in $str in turn
}
Run Code Online (Sandbox Code Playgroud)

另一种使用方式/g是在列表上下文中:

my @results = $str =~ /pattern/g; # collect each occurence of 'pattern' within $str into @results
Run Code Online (Sandbox Code Playgroud)

如果你/g在标量上下文中使用并且你没有迭代它,你几乎肯定没有正确使用它.

  • 啊!我知道我已经多次使用过这种情况(在循环中,特别是你描述的时候)我忘记了它的意思!现在这是有道理的.非常感谢! (2认同)

cjm*_*cjm 5

在Regexp Quote Like Operators上引用perlop:

在标量上下文中,每次执行都会m//g查找下一个匹配项,如果匹配则返回true,如果没有其他匹配项则返回false.可以使用该pos()功能读取或设置最后一次匹配后的位置; 见pos.失败的匹配通常会将搜索位置重置为字符串的开头,但您可以通过添加/c修饰符(例如m//gc)来避免这种情况.修改目标字符串也会重置搜索位置.

因此,在标量上下文(您正在使用)中,/g并不意味着"从头开始搜索",它意味着"从字符串开始搜索pos"."从头开始搜索"是默认值(不含/g).

/g通常在您想要查找字符串中的正则表达式的所有匹配项时使用,而不仅仅是第一次匹配.在列表上下文中,它通过返回所有匹配的列表来实现.在标量上下文中,它通过从上一次搜索停止的位置开始搜索(通常在循环中完成).