正则表达式替换引号外的空格(任何)

时间:2014-08-12 17:38:09

标签: php regex

假设我有这个字符串:

this is a "test for stackoverflow", with 'single quotes too' and "combined 'quotes single and double'"

我需要得到:

thisisa"test for stackoverflow",with'single quotes too'and"combined 'quotes single and double'"

这只是一个例子,但引号最多可以嵌套3个级别(" str' str" str"'")也是多行。我需要一个RegEx来替换引号之外的所有空格。

3 个答案:

答案 0 :(得分:3)

您可以使用此正则表达式:

$s = <<< EOF
this is a "test for stackoverflow" , with 'single quotes too' and "combined 'quotes single and double'"
EOF;
echo preg_replace('/(?| *(".*?") *| *(\'.*?\') *)| +/s', '$1', $s);

输出:

  

thisisa"test for stackoverflow",with'single quotes too'and"combined 'quotes single and double'"

答案 1 :(得分:0)

简单(*跳过)(* F)魔术!

使用以下正则表达式:

/(?:"[^"]++"|'[^']++')(*SKIP)(*F)|\s/

View a regex demo!

表达解释:

  • (?:"[^"]++"|'[^']++')匹配引号和引号内的所有内容。
  • (*SKIP)(*F)将指针跳到下一个位置并弃掉该匹配。
  • | (如果上述替代方案尚未放弃,则仅匹配以下内容
  • \s空白。

答案 2 :(得分:-1)

可能不是最优雅的解决方案,但它是一个开始(不支持单引号,不支持引用。以前替换它们并在以后替换它们):

<?PHP
    $str = "this is a  \"test for stackoverflow\", with 'single quotes too' and \"combined 'quotes single and double'\"";

    $cleared = clearString($str);
    $solution = "thisisa\"test for stackoverflow\",with'single quotes too'and\"combined 'quotes single and double'\"";

    assert($cleared == $solution);

    function copyQuote($str, $until, $offset = 0)
    {
        $p = strpos($str, $until, $offset);

        if ($p !== FALSE)
            return substr($str, $offset, $p-$offset);
        else
            throw new Exception("Unclosed Quote Exception at position ".$offset);
    }

    function clearString($str)
    {
        $retVal = "";

        $len = strlen($str);
        for ($i = 0; $i < $len; $i++)
        {
            if ($str[$i] == "\"" || $str[$i] == "'")
            {
                $quote = copyQuote($str, $str[$i], $i+1);
                $retVal .= $str[$i].$quote.$str[$i];
                $i += strlen($quote)+1;
            } else {
                // Skip whitespaces outside of quotes, add any other check you'd like to do here
                if ($str[$i] != " " && $str[$i] != "\t")
                {
                    $retVal .= $str[$i];
                }
            }
        }
        return $retVal;
    }
?>