我从正则表达式中获得了一些意想不到的结果,这意味着要替换名称空间上的类名。替换似乎发生了两次,因此被替换的类名是重复的(参见下面的示例)。
我实际上已经通过将reg ex更改为匹配1或更多(+
)而不是0或更多(*
)来解决问题,这实际上对于我想要的更准确。< / p>
然而,我有点困惑为什么我首先遇到问题。
以下是问题的一个示例:
$classns = 'components\groups\GroupsController';
$newclass = 'GroupsAccess';
$classns = preg_replace('/[^\\\\]*$/', $newclass, $classns);
echo $classns;
结果
components\groups\GroupsAccessGroupsAccess
预期
components\groups\GroupsAccess
*是否可能与字边界或某种性质相匹配?
对我来说令人困惑的部分是使用相同正则表达式的preg_match只显示一个结果,因此它似乎是preg_match如何运行正则表达式的特定内容。
e.g。
preg_match('/[^\\\\]*$/', $classns, $m);
var_dump($m);
结果
array(1) { [0]=> string(12) "GroupsAccess" }
答案 0 :(得分:5)
*
与字边界不匹配,匹配空字符串。
您的表达式首先匹配
components \ groups \ GroupsController
并且$
是一个匹配位置的锚点,它位于字符串结尾之前(或者字符串结尾之前的\n
)。
所以在第一次匹配之后,正则表达式解析器的位置在最后一个“r”之后和字符串结尾之前,当它再次尝试匹配你的正则表达式时。它会找到一个匹配==&gt; 0次出现/
(空字符串),后跟字符串结尾。
然后它继续前进,识别字符串的结尾并完成。
答案 1 :(得分:2)
缩小它,这也显示两个匹配:
preg_match_all('/a*$/', 'a', $m);`
Python具有相同的行为:
>>> re.findall('a*$', 'a')
['a', '']
Perl也是如此:
>>> my @m = 'a' =~ /a*$/g;
>>> foreach (@m) { print "$_\n"; }
a
<blank>
似乎正则表达式引擎匹配'a'
和跟随它的空字符串''
。从技术上讲这是正确的,虽然这是令人惊讶的。 'a'
是一个锚定在搜索字符串末尾的字符串,''
也是。
匹配的一个基本规则是匹配不重叠。一旦找到匹配,正则表达式引擎将继续在上一场比赛结束时搜索下一场比赛。我没想到的是,锚$
可以被重用,大概是因为它是零宽度断言,而不是实际的子串匹配。