Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php->;预更换->;仅删除引号之间的空格_Php_Regex_Preg Replace - Fatal编程技术网

php->;预更换->;仅删除引号之间的空格

php->;预更换->;仅删除引号之间的空格,php,regex,preg-replace,Php,Regex,Preg Replace,我试图删除引号之间的空格,如: $text = 'good with spaces "here all spaces should be removed" and here also good'; 有人能帮我写一段代码吗?我已经试过了: $regex = '/(\".+?\")|\s/'; 或 没有成功,我发现了一个工作方向错误的示例:-( 但我不能改变它 thx Newi请参阅以下代码片段: <?php $text = 'good with spaces "here all spac

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

$text = 'good with spaces "here all spaces should be removed" and here also good';
有人能帮我写一段代码吗?我已经试过了:

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

没有成功,我发现了一个工作方向错误的示例:-( 但我不能改变它


thx Newi

请参阅以下代码片段:

<?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";
?>

使用
preg\u replace\u callback
可以轻松解决此类问题。其思想是提取引号之间的子字符串,然后在回调函数中对其进行编辑:

$text = preg_replace_callback('~"[^"]*"~', function ($m) {
    return preg_replace('~\s~', '#', $m[0]);
}, $text);
这是最简单的方法


使用带有
preg\u replace
的单个模式执行此操作更为复杂,但也有可能:

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

图案详情:

(?:
    \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 |“(*跳过)(*F))~

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

    ~(?:\G(?!\A)|“[^”\s\\\]*+(?:\\\\\\s[^”\s\\\]*)*+(?:\\\\?\K\s\\”(*跳过)(*F))


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

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

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

显示您已经尝试过的内容,即使它不起作用。您希望得到什么样的输出?我认为OP希望将
$text='与空格配合良好'这里所有的空格都应该被删除“这里也很好”;
变成
$text='good with spaces“hereallspaces shouldberemoved”和这里也很好“;
这些观察最好是在编辑原始问题时完成的;答案是为了提供问题的有效解决方案。哇……它很好:-)))))谢谢如果答案有效,你应该接受它并投票表决。太好了。如果引号内没有引号,可能还有另一种方法:
(?:
    \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.)
)
\s(?=[^"]*+(?:"[^"]*"[^"]*)*+")