具有全局替换的perl regexp中的奇怪行为

rco*_*out 17 regex perl

可以解释为什么这个小的perl脚本的输出是"foofoo"(而不是"foo")?

#!/usr/bin/perl -w 
my $var="a";
$var=~s/.*/foo/g;
print $var."\n";
Run Code Online (Sandbox Code Playgroud)

没有g选项它可以工作,虽然它会,但为什么全局选项匹配模式两次?

在bash中,输出是"foo",如预期的那样

echo "a"|sed -e "s/.*/foo/g" 
Run Code Online (Sandbox Code Playgroud)

任何解释将不胜感激.

yst*_*sth 12

首先.*匹配a,然后匹配a之后的空字符串.也许你想要.+

  • @rcout:贪婪与重复匹配的次数有关,它不会以某种方式超越字符串的结尾 (2认同)

Jav*_*ock 8

如果你尝试,它会更有趣

$var=~s/.*?/foo/g;
Run Code Online (Sandbox Code Playgroud)

你会得到

foofoofoo
Run Code Online (Sandbox Code Playgroud)

的?修饰符匹配1或0次.如果你删除g,你会得到

fooa

因为它只会替换空字符串,而是它找到的第一个字符串.我爱perl.


KJP*_*KJP 6

这是因为你使用的是.*代替.+

*修饰符告诉正则表达式引擎匹配(并在您的示例中替换)字符串"a",然后是零长度字符串(并替换它).

您可以在示例代码中使用此正则表达式对此进行测试:

$var=~s/(.*)/<$1>/g;
Run Code Online (Sandbox Code Playgroud)

然后,您将看到此输出:

"<a><>"
Run Code Online (Sandbox Code Playgroud)


too*_*lic 6

如果您在代码中添加re:

use re 'debug';
Run Code Online (Sandbox Code Playgroud)

你会看到正则表达式成功匹配两次:

Compiling REx `.*'
size 3 Got 28 bytes for offset annotations.
first at 2
   1: STAR(3)
   2:   REG_ANY(0)
   3: END(0)
anchored(MBOL) implicit minlen 0
Offsets: [3]
        2[1] 1[1] 3[0]
Matching REx ".*" against "a"
  Setting an EVAL scope, savestack=5
   0 <> <a>               |  1:  STAR
                           REG_ANY can match 1 times out of 2147483647...
  Setting an EVAL scope, savestack=5
   1 <a> <>               |  3:    END
Match successful!
Matching REx ".*" against ""
  Setting an EVAL scope, savestack=7
   1 <a> <>               |  1:  STAR
                           REG_ANY can match 0 times out of 2147483647...
  Setting an EVAL scope, savestack=7
   1 <a> <>               |  3:    END
Match successful!
Matching REx ".*" against ""
  Setting an EVAL scope, savestack=7
   1 <a> <>               |  1:  STAR
                           REG_ANY can match 0 times out of 2147483647...
  Setting an EVAL scope, savestack=7
   1 <a> <>               |  3:    END
Match possible, but length=0 is smaller than requested=1, failing!
                            failed...
Match failed
foofoo
Freeing REx: `".*"'
Run Code Online (Sandbox Code Playgroud)