Php 删除字符串中未包含在单引号或双引号中的所有空格

Php 删除字符串中未包含在单引号或双引号中的所有空格,php,regex,string,Php,Regex,String,我有这样的短弦 $str = 'abc | xx ?? "1 x \' 3" d e f \' y " 5 \' x yz'; 我想删除字符串中未包含在单引号或双引号中的所有空格。 不应更改单引号或双引号中的任何字符。 因此,我预计: $expected = 'abc|xx??"1 x \' 3"def\' y " 5 \'xyz'; 我目前基于字符比较的解决方案如下: function removeSpaces($strin

我有这样的短弦

$str = 'abc | xx ??   "1 x \' 3" d e f \' y " 5 \' x yz';
我想删除字符串中未包含在单引号或双引号中的所有空格。 不应更改单引号或双引号中的任何字符。 因此,我预计:

$expected =  'abc|xx??"1 x \' 3"def\' y " 5 \'xyz';
我目前基于字符比较的解决方案如下:

function removeSpaces($string){
  $ret = $stop = "";
  for($i=0; $i < strlen($string);$i++){
    $char = $string[$i];
    if($stop == "") {
      if($char == " ") continue;
      if($char == "'" OR $char == '"') $stop = $char;
    }
    else {
      if($char == $stop) $stop = "";
    }
    $ret .= $char;
  }
  return $ret;
}
函数removespace($string){
$ret=$stop=“”;
对于($i=0;$i
有更智能的解决方案吗?

您可以使用

preg_replace('~(?<!\\\\)(?:\\\\{2})*(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')(*SKIP)(?!)|\s+~s', '', $str)
preg_replace('~(?您可以使用

preg_replace('~(?<!\\\\)(?:\\\\{2})*(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')(*SKIP)(?!)|\s+~s', '', $str)

preg\u replace(“~(?您可以在一个组中捕获
,并使用任何转义变量或每个变量,直到遇到结束匹配的
,使用反向引用
\1

(?<!\\)(['"])(?:(?!(?:\1|\\)).|\\.)*+\1(*SKIP)(*FAIL)|\h+

您可以在组中捕获
,并使用任何转义变量或每个变量,直到遇到结束匹配的
,使用反向引用
\1

(?<!\\)(['"])(?:(?!(?:\1|\\)).|\\.)*+\1(*SKIP)(*FAIL)|\h+

这里有三个步骤:

  • 用占位符替换引号部分中的空格
  • 删除所有空格
  • 恢复引号部分中的空格
  • 输出:

    input:  abc | xx ??   "1 x ' 3" d e f ' y " 5 ' x yz
    result: abc|xx??"1 x ' 3"def' y " 5 'xyz
    expect: abc|xx??"1 x ' 3"def' y " 5 'xyz
    
    说明:

  • 用占位符替换引号部分中的空格
    • 使用
      preg\u replace\u回调()
    • “|”([“\”)(.*)(\1)|”与以
      ”开头和结尾的引号部分相匹配。
    • (\1)
      确保与收盘报价匹配(要么
      要么
    • 在回调中,使用
      preg\u replace()
      将所有空格替换为不可打印的替换内容
      “\x01”
  • 删除所有空格
    • 使用
      preg\u replace()
      删除所有空格
    • 替换项与替换项
      “\x01”
      不匹配,因此缺少引号部分中的空格
  • 恢复引号部分中的空格
    • 使用
      preg\u replace()
      从替换中还原所有空格
      “\x01”

      • 以下是一个三步方法:

      • 用占位符替换引号部分中的空格
      • 删除所有空格
      • 恢复引号部分中的空格
      • 输出:

        input:  abc | xx ??   "1 x ' 3" d e f ' y " 5 ' x yz
        result: abc|xx??"1 x ' 3"def' y " 5 'xyz
        expect: abc|xx??"1 x ' 3"def' y " 5 'xyz
        
        说明:

      • 用占位符替换引号部分中的空格
        • 使用
          preg\u replace\u回调()
        • “|”([“\”)(.*)(\1)|”与以
          ”开头和结尾的引号部分相匹配。
        • (\1)
          确保与收盘报价匹配(要么
          要么
        • 在回调中,使用
          preg\u replace()
          将所有空格替换为不可打印的替换内容
          “\x01”
      • 删除所有空格
        • 使用
          preg\u replace()
          删除所有空格
        • 替换项与替换项
          “\x01”
          不匹配,因此缺少引号部分中的空格
      • 恢复引号部分中的空格
        • 使用
          preg\u replace()
          从替换中还原所有空格
          “\x01”

        d e f\'y
        随附在
        ,这里的规则是什么?找到第一个引号,然后,如果/当找到下一个引号时,开始删除空格?处理方法与PHP解释器相同。双引号中包含的单引号和单引号中包含的双引号与任何其他字符一样处理。@fourthbird请不要将答案作为注释。
        def\'y
        附在
        "
        ,这里的规则是什么?找到第一个引号,然后,如果/当找到下一个引号时,开始删除空格?处理方法与PHP解释器相同。双引号中包含的单引号和单引号中包含的双引号与任何其他字符一样处理。@fourthbird请不要将答案作为评论。我不会使用需要另一个
        preg\uuu
        调用才能嵌套在其中的
        preg\uu
        调用,并且还需要另外两个
        preg\uuu
        调用才能在最后完成。你认为你的新答案会以什么方式增加这一页的价值?@mickmackusa:因为一个问题通常有多个答案/我认为这很好给出选项。让读者决定什么有用,什么不有用。但是如果你已经知道你的答案效率较低(因为它会进行多次
        preg\u
        调用,而之前的答案只进行1次
        preg\u
        调用),那么你的答案只会浪费研究人员的时间,而他们阅读的答案没有任何益处。因此,我再次向你提出的问题是:与其他答案相比,这个效率较低、不太直接、更冗长的答案有什么价值?它是否以某种方式提高了准确性?我不知道,因为我没有测试任何答案,但我无法验证我认为Wiktor的答案是可靠的。@mickmackusa:我同意,对于这个特定的用例,单行正则表达式更容易,而且可能更快。这个答案的价值:学习和教育。在一些用例中,多程正则表达式可以有效地解决复杂的问题,例如解析嵌套结构:我不会使用
        preg
        这需要在其中嵌套另一个
        preg
        调用…并且还需要另外两个
        preg
        调用才能在最后完成。你认为你的新答案会以什么方式为这一页增加价值?@mickmackusa:因为一个问题通常有多个答案/我认为给出选项是很好的。让我们重新开始吧你可以决定什么有用,什么不有用。但如果你已经知道你的答案效率较低(请谨慎)