php - 正则表达式 (PHP) 删除除引号之间的所有水平空格(“”和 '')(包括转义引号)
问题描述
使用 preg_replace (PHP) 我想删除所有水平空格,除了引号之间的空格(“”和 '')(包括转义引号)
一个例子(正则表达式应该在右侧转向左侧):
2 + 2 => 2+2
f( " ") => f(" ")
f("Test \"mystring\" .") => f("Test \"mystring\" .")
f("' ", " ") => f("' "," ")
使用我想出的
另一篇文章:\h(?=[^']*(?:'[^']*'[^']*)*$)(?=[^"]*(?:"[^"]*"[^"]*)*$)
它基本上向前看并检查在字符串结尾之前是否有偶数的引号(“”和“”)。
但是,我遇到转义字符和引号内的引号问题。
" ' test " => The ' causes problem
" \" test " => The \" causes problem
我曾想过使用负面的lookbehinds:(?<!\\)"
但无法让它发挥作用。下一个正则表达式失败。当字符串包含转义引号时,它不匹配。
\h(?=[^"]*(?:(?<!\\)"(?:[^"]*?(?<!\\)")[^"]*?)*$)
解决方案
您可以使用
'~(?<!\\\\)(?:\\\\{2})*(?:"[^\\\\"]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')(*SKIP)(*F)|\h+~s'
查看正则表达式演示
细节
(?<!\\)(?:\\{2})*(?:"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*')(*SKIP)(*F)
- 一个'...'
或"...."
子字符串,其中第一个引号本身没有转义,一旦匹配就会被跳过(因此,它们内部的任何内容都不会被删除)(?<!\\)
-\
当前位置左侧不允许有字符(?:\\{2})*
- 零次或多次重复双反斜杠(?:"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*')
- 两种选择之一:"[^\\"]*(?:\\.[^"\\]*)*"
- 双引号内的字符串文字"
- 双引号[^\\"]*
- 0 个或多个字符,而不是\
and"
(?:\\.[^"\\]*)*"
- 零次或多次重复 a\
后跟任何字符 (\\.
),然后是除"
and\
([^"\\]*
)以外的任何 0 个或多个字符|
- 或者'[^\\']*(?:\\.[^'\\]*)*'
- 单引号内的字符串文字
(*SKIP)(*F)
- 省略找到的匹配项并使正则表达式引擎继续搜索从当前正则表达式索引开始的下一个匹配项的 PCRE 动词
|\h+
- 或 1 个或多个水平空格
$strs = ['2 + 2', 'f( " ")', 'f("Test \\"mystring\\" .")', 'f("\' ", " ")'];
$rx = '~(?<!\\\\)(?:\\\\{2})*(?:"[^\\\\"]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')(*SKIP)(*F)|\h+~s';
print_r( preg_replace($rx, '', $strs) );
输出:
Array
(
[0] => 2+2
[1] => f(" ")
[2] => f("Test \"mystring\" .")
[3] => f("' "," ")
)
推荐阅读
- docker - Is there way in docker compose to create the cross service constant?
- azure - Azure VM 和 VN 连接
- oracle - Oracle中的uno和dual有什么区别?
- java - 在当前主题中找不到样式“chipIconSize”
- c - C 内存地址和值
- angular - 更改角材料中的复选框颜色
- javascript - 在 JS textContent 更改时触发 CSS 动画
- python - 使用pytorch沿任意维度映射函数?麻木?
- angular - 角度5:应用程序组件重绘几次
- python - 管道 PCA,我可以从这个内置函数中提取加载向量吗