php - > preg_replace - >仅在引号之间删除空格

时间:2018-05-13 18:38:40

标签: php regex preg-replace

我试图仅在引号之间删除空格,如:

$text = 'good with spaces "here all spaces should be removed" and here also good';

有人可以帮助处理一段代码吗?我已经尝试过了:

$regex = '/(\".+?\")|\s/';

$regex = '/"(?!.?\s+.?)/';

没有成功,我发现了一个在错误方向上工作的样本:-( Removing whitespace-characters, except inside quotation marks in PHP?但我无法改变它。

thx Newi

2 个答案:

答案 0 :(得分:3)

使用preg_replace_callback可以轻松解决此类问题。这个想法包括提取引号之间的子串,然后在回调函数中编辑它:

$text = preg_replace_callback('~"[^"]*"~', function ($m) {
    return preg_replace('~\s~', '#', $m[0]);
}, $text);

这是最简单的方法。

使用preg_replace的单一模式执行此操作会更复杂但是可能:

$text = preg_replace('~(?:\G(?!\A)|")[^"\s]*\K(?:\s|"(*SKIP)(*F))~', '#', $text);

demo

模式细节:

(?:
    \G (?!\A)  # match the next position after the last successful match
  |
    "          # or the opening double quote
)
[^"\s]*        # characters that aren't double quotes or a whitespaces
\K             # discard all characters matched before from the match result
(?:
    \s         # a whitespace
  |
    "           # or the closing quote
    (*SKIP)(*F) # force the pattern to fail and to skip the quote position
                # (this way, the closing quote isn't seen as an opening quote
                # in the second branch.)
)

这种方式使用\G锚来确保所有匹配的空格都在引号之间。

边缘情况:

  • 这是一个孤儿开场语:在这种情况下,从最后一个引号到字符串结尾的所有空格都被替换掉。但是,如果您需要,可以更改此行为,添加前瞻以检查结束引用是否存在:

    ~(?:\G(?!\A)|"(?=[^"]*"))[^"\s]*\K(?:\s|"(*SKIP)(*F))~

  • 双引号可以包含必须忽略的转义双引号:您必须描述这样的转义字符:

    ~(?:\G(?!\A)|")[^"\s\\\\]*+(?:\\\\\S[^"\s\\\\]*)*+(?:\\\\?\K\s|"(*SKIP)(*F))~

@revo建议的其他策略:检查某个位置的剩余报价数是奇数还是使用前瞻:

\s(?=[^"]*+(?:"[^"]*"[^"]*)*+")

这是一个简短的模式,但是对于长字符串可能会有问题,因为对于每个具有空格的位置,您必须检查字符串,直到最后一个带有前瞻的引用。

答案 1 :(得分:0)

请参阅以下代码段:

<?php
$text = 'good with spaces "here all spaces should be removed" and here also good';
echo "$text \n";
$regex = '/(\".+?\")|\s/';
$regex = '/"(?!.?\s+.?)/';
$text = preg_replace($regex,'', $text);
echo "$text \n";
?>

我发现a sample that works的方向错误: - (

<小时/> @Graham:正确

$text = 'good with spaces "here all spaces should be removed" and here also good'
should be 
$text = 'good with spaces "hereallspacesshouldberemoved" and here also good';