You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写PCRE正则匹配PHP双引号字符串,排除单引号内双引号

解决PHP双引号字符串PCRE正则匹配问题

针对需求——匹配PHP代码中的双引号字符串(支持转义双引号),同时排除单引号字符串内部的双引号(比如HTML属性转义的"场景),可以采用先排除单引号区域,再匹配双引号字符串的方案,避免长度不固定环视的编译错误。

最终正则表达式

'[^'\\]*(?:\\.[^'\\]*)*'(*SKIP)(*FAIL)|"[^"\\]*(?:\\.[^"\\]*)*"

规则解释

1. 单引号区域排除逻辑

'[^'\\]*(?:\\.[^'\\]*)*'(*SKIP)(*FAIL)

  • ':匹配单引号字符串的起始标记
  • [^'\\]*:匹配任意数量的非单引号、非反斜杠字符
  • (?:\\.[^'\\]*)*:非捕获组,处理单引号内的转义序列(如\'):先匹配反斜杠+任意字符,再继续匹配非单引号/反斜杠字符,循环至遇到未转义的单引号
  • ':匹配单引号字符串的结束标记
  • (*SKIP)(*FAIL):PCRE专属标记,标记该区域为“跳过匹配”,后续规则不会处理这部分内容

2. 双引号字符串匹配逻辑

"[^"\\]*(?:\\.[^"\\]*)*"

  • ":匹配双引号字符串的起始标记
  • [^"\\]*:匹配任意数量的非双引号、非反斜杠字符
  • (?:\\.[^"\\]*)*:非捕获组,处理双引号内的转义序列(如\"),逻辑同单引号内的转义处理
  • ":匹配双引号字符串的结束标记

效果验证

针对你提供的示例代码:

$str = '<elem prop=&quot;' . $var . '&quot;>';
$str = '<div class=&quot;my-class ' . $my_var_class . ' my-other-class&quot;>';

正则会跳过所有单引号包裹的内容(包括其中的&quot;里的双引号),不会产生错误匹配;而对于真正的PHP双引号字符串(如$str = "Hello \"World\"";),则能准确匹配整个"Hello \"World\""部分。

为什么优于原正则

原正则"(.*?)(?<!\\)"采用非贪婪匹配+负向环视,存在两个问题:

  • 无法区分双引号是否处于单引号字符串内部,导致错误匹配HTML属性转义的场景
  • 若尝试用长度不固定的环视(如(?<!'[^']*))排除单引号区域,会触发PCRE“环视断言长度不固定”的编译错误

而(*SKIP)(*FAIL)机制通过先排除不需要的区域,从根源上避免了上述问题,且匹配效率更高。

内容的提问来源于stack exchange,提问作者inventor96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:22:34