将preg_replace()e修饰符replace为preg_replace_callback
我用正则expression式很糟糕。 我试图取代这个:
public static function camelize($word) { return preg_replace('/(^|_)([az])/e', 'strtoupper("\\2")', $word); }
带有匿名函数的preg_replace_callback。 我不明白“2”在做什么。 或者就此而言,preg_replace_callback是如何工作的。
什么是实现这个正确的代码?
在正则expression式中,可以用(brackets)
“捕获”匹配string的部分; 在这种情况下,您正在捕获匹配的(^|_)
和([az])
部分。 这些从1开始编号,所以你有反向引用1和2.匹配0是整个匹配的string。
/e
修饰符需要一个replacestring,用相应的反向引用replace反斜杠后面跟一个数字(例如\1
) – 但是因为你在一个string内,所以你需要转义反斜杠,所以你得到'\\1'
。 然后(有效地)运行eval
来运行结果string,就好像它是PHP代码一样(这就是为什么它被弃用,因为它很容易以不安全的方式使用eval
)。
preg_replace_callback
函数取而代之的是一个callback函数,并向它传递一个包含匹配反向引用的数组。 所以,如果你写了'\\1'
,你可以访问该参数的元素1,例如,如果你有一个函数formsfunction($matches) { ... }
的匿名函数,那么第一个返回引用是$matches[1]
里面的function。
所以, /e
'do_stuff(\\1) . "and" . do_stuff(\\2)'
可以成为一个callback
function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); }
或者在你的情况
'strtoupper("\\2")'
可能成为
function($m) { return strtoupper($m[2]); }
请注意, $m
和$matches
不是不可思议的名称,它们只是我在声明callback函数时给出的参数名称。 另外,你不必传递一个匿名函数,它可以是一个函数名string,也可以是array($object, $method)
formsarray($object, $method)
, 就像PHP中的任何callback函数一样,例如
function stuffy_callback($things) { return do_stuff($things[1]) . "and" . do_stuff($things[2]); } $foo = preg_replace_callback('/([az]+) and ([az]+)/', 'stuffy_callback', 'fish and chips');
与任何函数一样,默认情况下,您不能访问callback之外的variables(来自周围的范围)。 当使用匿名函数时,可以使用use
关键字导入需要访问的variables, 如PHP手册中所讨论的 。 例如,如果旧的论点是
'do_stuff(\\1, $foo)'
那么新的callback可能看起来像
function($m) use ($foo) { return do_stuff($m[1], $foo); }