我试图仅删除引号之间的空格,例如:
$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?但我无法改变它。
谢谢纽维
最佳答案
此类问题可以通过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
anchor 来确保所有匹配的空格都位于引号之间。
边缘情况:
有一个孤立的左引号:在这种情况下,从最后一个引号到字符串末尾的所有空格都将被替换。但如果您愿意,可以更改此行为,添加前瞻来检查收盘价是否存在:
~(?:\G(?!\A)|"(?=[^"]*"))[^"\s]*\K(?:\s|"(*SKIP )(*F))~
双引号可以包含必须忽略的转义双引号:您必须像这样描述转义字符:
~(?:\G(?!\A)|")[^"\s\\\\]*+(?:\\\\\S[^"\s\\\\]*)*+(?:\\\\?\K\s|"(*SKIP)(*F))~
@revo 建议的其他策略:使用前瞻检查某个位置的剩余报价数量是奇数还是偶数:
\s(?=[^"]*+(?:"[^"]*"[^"]*)*+")
这是一个短模式,但对于长字符串可能会出现问题,因为对于每个带有空格的位置,您必须检查字符串,直到最后一个带有前瞻的引号。
关于php -> preg_replace -> 仅删除引号之间的空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50319434/