将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); }