用 preg_replace_callback 替换 preg_replace() e 修饰符 [英] Replace preg_replace() e modifier with preg_replace_callback

查看:51
本文介绍了用 preg_replace_callback 替换 preg_replace() e 修饰符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对正则表达式很糟糕.我正在尝试替换它:

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

使用带有匿名函数的 preg_replace_callback.我不明白 \2 在做什么.或者就此而言, preg_replace_callback 究竟是如何工作的.

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.

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

What would be the correct code for achieving this?

推荐答案

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

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.

/e 修饰符接受一个替换字符串,并用适当的反向引用替换反斜杠后跟一个数字(例如 1) - 但因为你是在字符串中,您需要对反斜杠进行转义,因此您会得到 '\1'.然后(有效地)运行 eval 来运行结果字符串,就好像它是 PHP 代码一样(这就是它被弃用的原因,因为它很容易以不安全的方式使用 eval).

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).

preg_replace_callback 函数接受一个回调函数,并将包含匹配的反向引用的数组传递给它.因此,在您编写 '\1' 的地方,您可以访问该参数的元素 1 - 例如如果您有 function($matches) { ... } 形式的匿名函数,则第一个反向引用是该函数内的 $matches[1].

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.

所以

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

可能成为

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

或者你的情况

'strtoupper("\2")'

可能变成

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

请注意,$m$matches 不是魔术名称,它们只是我在声明回调函数时给出的参数名称.此外,您不必传递匿名函数,它可以是字符串形式的函数名称,也可以是 array($object, $method), 与 PHP 中的任何回调一样,例如

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.

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');

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

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

'do_stuff(\1, $foo)'

那么新的回调可能看起来像

then the new callback might look like

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

问题

  • 使用 preg_replace_callback 而不是 正则表达式上的 /e 修饰符,因此您需要从模式"中删除该标志争论.所以像 /blah(.*)blah/mei 这样的模式会变成 /blah(.*)blah/mi.
  • /e 修饰符在参数内部使用了 addslashes() 的变体,因此一些替换使用 stripslashes() 将其删除;在大多数情况下,您可能希望从新回调中删除对 stripslashes 的调用.
  • 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.
    • 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.
    • 这篇关于用 preg_replace_callback 替换 preg_replace() e 修饰符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆