我试图仅在引号之间删除空格,如:
$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
答案 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);
模式细节:
(?:
\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';