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

具有全局替换的perl regexp中的奇怪行为,regex,perl,Regex,Perl,有人能解释一下为什么这个小perl脚本的输出是“foooo”(而不是“foo”) 如果没有g选项,它的工作原理与我想象的一样,但为什么全局选项会匹配两次呢 在bash中,输出是预期的“foo” echo "a"|sed -e "s/.*/foo/g" 任何解释都将不胜感激。首先*匹配a,然后匹配a后面的空字符串。也许你想要+?这是因为你使用的是*而不是+ *修饰符告诉正则表达式引擎匹配(并在您的示例中替换)字符串“a”,然后是零长度字符串(并替换) 您可以在示例代码中使用此正则表达式来测试这

有人能解释一下为什么这个小perl脚本的输出是“foooo”(而不是“foo”)

如果没有g选项,它的工作原理与我想象的一样,但为什么全局选项会匹配两次呢

在bash中,输出是预期的“foo”

echo "a"|sed -e "s/.*/foo/g" 

任何解释都将不胜感激。

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

这是因为你使用的是
*
而不是
+

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

您可以在示例代码中使用此正则表达式来测试这一点:

$var=~s/(.*)/<$1>/g;
$var=~s/(.*)//g;
然后您将看到以下输出:

"<a><>"
“”
如果在代码中添加:

use re 'debug';
您将看到正则表达式成功匹配了两次:

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: `".*"'
编译REx`.*
大小3为偏移量批注获取了28个字节。
2点开始
1:星(3)
2:REG_ANY(0)
3:完(0)
锚定(MBOL)隐式最小值0
抵销:[3]
2[1] 1[1] 3[0]
匹配REx“*”和“a”
设置评估范围,savestack=5
0 | 1:星
REG_ANY可以匹配2147483647中的1次。。。
设置评估范围,savestack=5
1 | 3:结束
比赛成功!
匹配REx“*”与“”
设置评估范围,savestack=7
1 | 1:星
REG_ANY可以匹配2147483647中的0次。。。
设置评估范围,savestack=7
1 | 3:结束
比赛成功!
匹配REx“*”与“”
设置评估范围,savestack=7
1 | 1:星
REG_ANY可以匹配2147483647中的0次。。。
设置评估范围,savestack=7
1 | 3:结束
可能匹配,但长度=0小于请求的长度=1,失败!
失败。。。
比赛失败
福福
释放雷克斯:`.*''

如果你尝试一下,会更有趣

$var=~s/.*?/foo/g;
你会得到

foofoofoo
那个?修饰符匹配1或0次。如果你去掉g,你会得到

foofoofoo
福阿


因为它只会替换它找到的第一个空字符串。我喜欢perl。

是的,就是这样,我相信
$var=~s/^.*/foo/g
没有意识到它会匹配空字符串,但事实上这是一种明显的现象。仔细想想,*应该是贪婪的,怎么回事?@rcout:greediness与重复匹配的次数有关,它不会以某种方式超过字符串的结尾