【问题标题】:How to match all php variables inside double quotes如何匹配双引号内的所有php变量
【发布时间】:2016-09-08 06:01:00
【问题描述】:

我需要在里面替换$bar

"foo$bar baz"

还有$foo$bar在里面:

"xxx $foo xxx $bar"

有一定的价值。到目前为止,我有匹配所有变量的正则表达式,那么多 php 变量,但不是在不是对象和方法调用的单引号内:

%'[^']+'(*SKIP)(*F)|(?<!\\\\)\\$([\w./]+)\b(?!->)%

我使用 json_encode 替换值,但如果值在双引号内,我不想使用 json_encode,因此 "$foo" 的值不会是 ""something""

我试过这段代码:

while(preg_match('%("(?:[^"]|\\\\")+?)\\$([\w./]+)\b(?!->)%', $str)) {
    $str = preg_replace_callback('%("(?:[^"]|\\\\")+?)\\$([\w./]+)\b(?!->)%', function($matches) use ($context, $self) {
        return $matches[1] . $self->get_context_var($context, $matches[2]);
    }, $str);
}

但是当有这个字符串时它不起作用:

"/$username|$username/" && $username != ""

它替换了第三个 $username 它不应该匹配那个。

【问题讨论】:

  • eval('$result = "xxx $foo xxx $bar";');
  • 当文字 $ 之前有文字反斜杠时,您拥有的这个正则表达式会在转义序列上绊倒。正则表达式解决方案在这里不是 100% 安全的。
  • 代码 sn-p 总是那么简单吗?还是可以任意复杂(例如整个脚本)?如果它是任意复杂的,你不能这样做。无论多么强大,你都不能编写一个可以实现完整 PHP 代码解析器的正则表达式。
  • @MarcB 我不想要完整的解析器我只需要这个简单的案例,双引号内的 php 变量。
  • 那你为什么不能使用简单的字符串替换呢? str_replace($your_string, '$foo', 'whatever foo should be')?

标签: php regex


【解决方案1】:

更新

可以一步完成,在替换所有普通$vars 的同时,捕获双引号字符串并将其中的$vars 替换为不同的内容(考虑双引号字符串中的转义字符):

Live demo

preg_replace_callback('~\'[^\']+\'(*SKIP)(*F)|"(?<double>[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|(?<!\\\\)\$([\w.\/]+)\b(?!->)~', function($match) {
    if (!empty($match['double'])) {
        return '"'.preg_replace('/(?<!\\\\)\$([\w.\/]+)\b(?!->)/', 'NOT_JSON_ENOCDE', $match['double']).'"';
    } else {
        return "JSON_ENOCDE";
    }
}, $str);

【讨论】:

  • 如果双引号像"foo\"$bar"一样被转义怎么办?
  • 感谢您的帮助。 PS:双引号字符串还是两步。
  • 不,这不是两个步骤,preg_replace() 是强制性的,您应该通过您的回答看到您的代码中有三个 preg_replace_callback 调用,这是不必要的。如果存在转义字符,您使用的正则表达式也不会捕获正确的部分 - check here
  • 你的解决方案几乎可以工作,它在空字符串上失败,我已经修复了使用这个正则表达式 '~\'[^\']+\'(*SKIP)(*F)|(?&lt;double&gt;"[^"\\\\]*(?:\\\\.[^"\\\\]*)*")|(?&lt;!\\\\)\$(?&lt;name&gt;[\w.\/]+)\b(?!-&gt;)~' 并删除 preg_replace 周围的引号
  • 正则表达式匹配字符串中奇数个转义引号作为字符串$re = '~\'[^\']+\'(*SKIP)(*F)|(?&lt;double&gt;(?&lt;!\\\\)"(?:(?:(?&lt;!\\\\)(?:\\\\{2})*\\\\)"|[^"])*(?&lt;![^\\\\]\\\\)")|(?&lt;!\\\\)\$(?&lt;name&gt;[\w.\/]+)\b(?!-&gt;)~';的一部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多