字符串中的正则表达式额外空格不是双引号或单引号 - PHP

时间:2012-04-09 14:14:12

标签: php regex

我想用一个空格替换多余的空格(连续空白字符的实例),只要这些额外的空格不是双引号或单引号(或我可能想要包含的任何其他外壳)。

我看到了一些类似的问题,但我找不到对上述需求的直接回应。谢谢!

2 个答案:

答案 0 :(得分:2)

你可以分几步完成。请考虑以下示例:

$str = 'This is    a string with  "Bunch of    extra  spaces". Leave them  "untouched  !".';

$id = 0;
$buffer = array();
$str = preg_replace_callback('|".*?"|', function($m) use (&$id, &$buffer) {
    $buffer[] = $m[0];
    return '__' . $id++;
}, $str);
$str = preg_replace('|\s+|', ' ', $str);
$str = preg_replace_callback('|__(\d+)|', function($m) use ($buffer) {
    return $buffer[$m[1]];
}, $str);

echo $str;

这将输出字符串:

This is a string with "Bunch of    extra  spaces". Leave them "untouched  !".

虽然这不是最漂亮的解决方案。

答案 1 :(得分:2)

希望你还在寻找,或者回来检查!这似乎对我有用:

'/\s+((["\']).*?(?=\2)\2)|\s\s+/'

...并替换为 $1

修改

此外,如果您需要允许转发引号,例如\"\',您可以使用此表达式:

 '/\s+((["\'])(\\\\\2|(?!\2).)*?(?=\2)\2)|\s\s+/'

如果您想添加对括号内“平衡”引号的支持(例如(){}

,会有点棘手

结束编辑

如果您发现问题或想要解释,请告诉我们!


HOPEFULLY FINAL EDIT AND WARNINGS

  • 潜在问题:如果带引号的字符串从字符串变量(或文件)的开头开始,它将不计为带引号的字符串(并且减少了任何空格),否则它会抛弃整个事物,做任何事情不在引号中被视为在引号中处理,反之亦然 -
    • 可能解决此问题的潜在变化是使用以下匹配表达式
    • /(?:^|\s+)((["\'])(\\\\\2|(?!\2).)*?(?=\2)\2)|\s\s+/
    • 这会在表达式
    • 的开头用\s+替换(?:^|\s+)
    • 这将在变量的开头添加一个空格如果字符串以引号开头 - 只需修剪()或删除该空格以继续
  • 我似乎使用了“逐行”方法(如sed,如果我没有记错的话)来达到我的原始结果 - 如果你使用“整个文件”或“整个字符串”设置或方法,运输-return-line-feed似乎算作两个空白字符(无法想象为什么......),因此将任何换行转换为单个空格(除非它们在引号内并且使用“dot-matches-newline”) )
    • 可以通过将.\s速记字符类替换为您要匹配的特定字符来解决此问题,如下所示:
    • /(?:^|[ \t]+)((["\'])(\\\\\2|(?!\2)[\s\S])*?(?=\2)\2)|[ \t]{2,}/
    • 这不需要dot-matches-newline开关,只需用一个空格替换多个空格或标签 - 而不是换行符(当然,只有他们没有被引用)

示例

This link显示了http://codepad.viper-7.com

上示例文字的第一个表达式和最后一个表达式的示例