用preg_replace_callback替换preg_replace()e修饰符

时间:2021-04-16 22:31:03

I'm terrible with regular expressions. I'm trying to replace this:

我对正则表达式很糟糕。我试图取代这个:

public static function camelize($word) {   return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word);}

with preg_replace_callback with an anonymous function. I don't understand what the \\2 is doing. Or for that matter exactly how preg_replace_callback works.

使用带有匿名函数的preg_replace_callback。我不明白\\ 2是做什么的。或者就此而言preg_replace_callback的工作原理。

What would be the correct code for achieving this?

实现这一目标的正确代码是什么?

2 个解决方案

#1


In a regular expression, you can "capture" parts of the matched string with (brackets); in this case, you are capturing the (^|_) and ([a-z]) parts of the match. These are numbered starting at 1, so you have back-references 1 and 2. Match 0 is the whole matched string.

在正则表达式中,您可以使用(括号)“捕获”匹配字符串的一部分;在这种情况下,您正在捕获匹配的(^ | _)和([a-z])部分。这些编号从1开始编号,因此您有后引用1和2.匹配0是整个匹配的字符串。

The /e modifier takes a replacement string, and substitutes backslash followed by a number (e.g. \1) with the appropriate back-reference - but because you're inside a string, you need to escape the backslash, so you get '\\1'. It then (effectively) runs eval to run the resulting string as though it was PHP code (which is why it's being deprecated, because it's easy to use eval in an insecure way).

/ e修饰符接受一个替换字符串,并用反斜杠替换后跟一个数字(例如\ 1)和相应的反向引用 - 但因为你在一个字符串中,你需要转义反斜杠,所以你得到'\\ 1。然后(有效地)运行eval来运行生成的字符串,就像它是PHP代码一样(这就是为什么它被弃用了,因为它很容易以不安全的方式使用eval)。

The preg_replace_callback function instead takes a callback function and passes it an array containing the matched back-references. So where you would have written '\\1', you instead access element 1 of that parameter - e.g. if you have an anonymous function of the form function($matches) { ... }, the first back-reference is $matches[1] inside that function.

preg_replace_callback函数改为使用回调函数,并将包含匹配的反向引用的数组传递给它。那么你在哪里写'\\ 1',你就可以访问该参数的元素1 - 例如如果你有一个表单函数的匿名函数($ matches){...},那么第一个反向引用是该函数内的$ matches [1]。

So a /e argument of

所以a / e论证

'do_stuff(\\1) . "and" . do_stuff(\\2)'

could become a callback of

可能成为回调

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); }

Or in your case

或者在你的情况下

'strtoupper("\\2")'

could become

function($m) { return strtoupper($m[2]); }

Note that $m and $matches are not magic names, they're just the parameter name I gave when declaring my callback functions. Also, you don't have to pass an anonymous function, it could be a function name as a string, or something of the form array($object, $method), as with any callback in PHP, e.g.

请注意,$ m和$ match不是魔术名称,它们只是我在声明我的回调函数时给出的参数名称。此外,您不必传递匿名函数,它可以是函数名作为字符串,也可以是表单数组($ object,$ method),就像PHP中的任何回调一样,例如:

function stuffy_callback($things) {    return do_stuff($things[1]) . "and" . do_stuff($things[2]);}$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips');

As with any function, you can't access variables outside your callback (from the surrounding scope) by default. When using an anonymous function, you can use the use keyword to import the variables you need to access, as discussed in the PHP manual. e.g. if the old argument was

与任何函数一样,默认情况下,您无法访问回调之外的变量(来自周围的范围)。使用匿名函数时,可以使用use关键字导入需要访问的变量,如PHP手册中所述。例如如果旧的论点是

'do_stuff(\\1, $foo)'

then the new callback might look like

然后新的回调可能看起来像

function($m) use ($foo) { return do_stuff($m[1], $foo); }

Gotchas

  • Use of preg_replace_callback is instead of the /e modifier on the regex, so you need to remove that flag from your "pattern" argument. So a pattern like /blah(.*)blah/mei would become /blah(.*)blah/mi.
  • 在正则表达式中使用preg_replace_callback而不是/ e修饰符,因此您需要从“pattern”参数中删除该标志。所以像/blah(.*)blah/mei这样的模式会成为/blah(.*)blah/mi。

  • The /e modifier used a variant of addslashes() internally on the arguments, so some replacements used stripslashes() to remove it; in most cases, you probably want to remove the call to stripslashes from your new callback.
  • / e修饰符在参数内部使用了addslashes()的变体,因此一些替换使用stripslashes()来删除它;在大多数情况下,您可能希望从新回调中删除对stripslashes的调用。

#2


You shouldn't use flag e (or eval in general).

你不应该使用标志e(或一般的eval)。

You can also use T-Regx library

您也可以使用T-Regx库

pattern('(^|_)([a-z])')->replace($word)->by()->group(2)->callback('strtoupper');

#1


In a regular expression, you can "capture" parts of the matched string with (brackets); in this case, you are capturing the (^|_) and ([a-z]) parts of the match. These are numbered starting at 1, so you have back-references 1 and 2. Match 0 is the whole matched string.

在正则表达式中,您可以使用(括号)“捕获”匹配字符串的一部分;在这种情况下,您正在捕获匹配的(^ | _)和([a-z])部分。这些编号从1开始编号,因此您有后引用1和2.匹配0是整个匹配的字符串。

The /e modifier takes a replacement string, and substitutes backslash followed by a number (e.g. \1) with the appropriate back-reference - but because you're inside a string, you need to escape the backslash, so you get '\\1'. It then (effectively) runs eval to run the resulting string as though it was PHP code (which is why it's being deprecated, because it's easy to use eval in an insecure way).

/ e修饰符接受一个替换字符串,并用反斜杠替换后跟一个数字(例如\ 1)和相应的反向引用 - 但因为你在一个字符串中,你需要转义反斜杠,所以你得到'\\ 1。然后(有效地)运行eval来运行生成的字符串,就像它是PHP代码一样(这就是为什么它被弃用了,因为它很容易以不安全的方式使用eval)。

The preg_replace_callback function instead takes a callback function and passes it an array containing the matched back-references. So where you would have written '\\1', you instead access element 1 of that parameter - e.g. if you have an anonymous function of the form function($matches) { ... }, the first back-reference is $matches[1] inside that function.

preg_replace_callback函数改为使用回调函数,并将包含匹配的反向引用的数组传递给它。那么你在哪里写'\\ 1',你就可以访问该参数的元素1 - 例如如果你有一个表单函数的匿名函数($ matches){...},那么第一个反向引用是该函数内的$ matches [1]。

So a /e argument of

所以a / e论证

'do_stuff(\\1) . "and" . do_stuff(\\2)'

could become a callback of

可能成为回调

function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); }

Or in your case

或者在你的情况下

'strtoupper("\\2")'

could become

function($m) { return strtoupper($m[2]); }

Note that $m and $matches are not magic names, they're just the parameter name I gave when declaring my callback functions. Also, you don't have to pass an anonymous function, it could be a function name as a string, or something of the form array($object, $method), as with any callback in PHP, e.g.

请注意,$ m和$ match不是魔术名称,它们只是我在声明我的回调函数时给出的参数名称。此外,您不必传递匿名函数,它可以是函数名作为字符串,也可以是表单数组($ object,$ method),就像PHP中的任何回调一样,例如:

function stuffy_callback($things) {    return do_stuff($things[1]) . "and" . do_stuff($things[2]);}$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips');

As with any function, you can't access variables outside your callback (from the surrounding scope) by default. When using an anonymous function, you can use the use keyword to import the variables you need to access, as discussed in the PHP manual. e.g. if the old argument was

与任何函数一样,默认情况下,您无法访问回调之外的变量(来自周围的范围)。使用匿名函数时,可以使用use关键字导入需要访问的变量,如PHP手册中所述。例如如果旧的论点是

'do_stuff(\\1, $foo)'

then the new callback might look like

然后新的回调可能看起来像

function($m) use ($foo) { return do_stuff($m[1], $foo); }

Gotchas

  • Use of preg_replace_callback is instead of the /e modifier on the regex, so you need to remove that flag from your "pattern" argument. So a pattern like /blah(.*)blah/mei would become /blah(.*)blah/mi.
  • 在正则表达式中使用preg_replace_callback而不是/ e修饰符,因此您需要从“pattern”参数中删除该标志。所以像/blah(.*)blah/mei这样的模式会成为/blah(.*)blah/mi。

  • The /e modifier used a variant of addslashes() internally on the arguments, so some replacements used stripslashes() to remove it; in most cases, you probably want to remove the call to stripslashes from your new callback.
  • / e修饰符在参数内部使用了addslashes()的变体,因此一些替换使用stripslashes()来删除它;在大多数情况下,您可能希望从新回调中删除对stripslashes的调用。

#2


You shouldn't use flag e (or eval in general).

你不应该使用标志e(或一般的eval)。

You can also use T-Regx library

您也可以使用T-Regx库

pattern('(^|_)([a-z])')->replace($word)->by()->group(2)->callback('strtoupper');