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

PHP使用preg_replace:移除水平空白但保留引号内含转义引号的空白

解决PHP中移除引号外水平空白但保留引号内空白的问题

要实现移除所有引号外的水平空白,同时保留单/双引号(包括转义引号)内的空白,关键是要准确区分“真正的引号边界”和“被转义的引号”,以及正确跳过引号内的内容。你之前的正则因为没有处理转义字符的场景,导致在遇到转义引号或引号嵌套时失效,我来给你一个可靠的解决方案:

最终实现代码

function removeOutsideWhitespace($input) {
    // 正则核心:匹配引号内的内容并跳过,只替换外部的水平空白
    $pattern = '/(?:(["\'])(?:\\.|(?!\1)[^\\])*\1)(*SKIP)(*FAIL)|\h/';
    return preg_replace($pattern, '', $input);
}

// 测试你的示例
echo removeOutsideWhitespace('2 + 2') . PHP_EOL; // 输出:2+2
echo removeOutsideWhitespace('f( " ")') . PHP_EOL; // 输出:f(" ")
echo removeOutsideWhitespace('f("Test \"mystring\" .")') . PHP_EOL; // 输出:f("Test \"mystring\" .")
echo removeOutsideWhitespace('f("\' ", " ")') . PHP_EOL; // 输出:f("\' "," ")
// 测试之前失效的场景
echo removeOutsideWhitespace('" \' test "') . PHP_EOL; // 输出:" ' test "(内部空格保留)
echo removeOutsideWhitespace('" \" test "') . PHP_EOL; // 输出:" \" test "(内部空格保留)

正则表达式详解

让我们拆解一下这个正则的逻辑:

  • (?:(["\'])(?:\\.|(?!\1)[^\\])*\1):匹配完整的引号包裹内容
    • (["\']):捕获当前匹配的引号(单引号或双引号)到分组1
    • (?:\\.|(?!\1)[^\\])*:匹配引号内的所有内容:
      • \\.:匹配任意转义字符(包括转义引号,比如\"或\')
      • (?!\1)[^\\]:匹配不是转义符、也不是当前分组1引号的普通字符
    • \1:匹配和分组1一致的闭合引号,确保引号成对
  • (*SKIP)(*FAIL):这是正则的“跳过匹配”技巧,告诉引擎:匹配到的这部分内容(引号内的部分)不需要处理,直接跳过
  • |\h:匹配所有未被跳过的水平空白字符,最终被替换为空字符串

这个方案完美解决了你之前遇到的问题:无论是转义引号、引号内嵌套其他引号,都能准确识别并保留内部的空白,只清理引号外的水平空白。

内容的提问来源于stack exchange,提问作者T. Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:25:19