正则表达式匹配空格但跳过部分

时间:2011-05-12 20:46:11

标签: php regex preg-replace preg-match whitespace

我理解,因为正则表达式基本上是无状态的,所以在不诉诸补充应用程序逻辑的情况下很难实现复杂的匹配,但我很想知道以下是否可行。

匹配所有空格,非常简单:\s+

但是在某些分隔符之间跳过空格,在我的情况下 <pre></pre> 单词nostrip

有没有任何技巧可以实现这一目标?我正在考虑两个单独的匹配,一个用于所有空格,一个用于 <pre> nostrip部分,并以某种方式否定后者

"This is some text NOSTRIP this is more text NOSTRIP some more text."
// becomes
"ThisissometextNOSTRIP this is more text NOSTRIPsomemoretext."

给定标签的嵌套 nostrip部分是无关紧要的,我不是要解析 HTML或任何东西,只是整理文本文件,但是出于显而易见的原因,在 <pre>阻止 nostrip部分中保存空白。< / p>

更好?


这最终是我的目标。我确信它可以在一些地方进行优化,但现在它可以很好地工作。

public function stripWhitespace($html, Array $skipTags = array('pre')){
    foreach($skipTags as &$tag){
        $tag = "<{$tag}.*?/{$tag}>";
    }
    $skipped = array();
    $buffer = preg_replace_callback('#(?<tag>' . implode('|', $skipTags) . ')#si',
        function($match) use(&$skipped){
            $skipped[] = $match['tag'];
            return "\x1D" . (count($skipped) - 1) . "\x1D";
        }, $html
    );
    $buffer = preg_replace('#\s+#si', ' ', $buffer);
    $buffer = preg_replace('#(?:(?<=>)\s|\s(?=<))#si', '', $buffer);
    for($i = count($skipped) - 1; $i >= 0; $i--){
        $buffer = str_replace("\x1D{$i}\x1D", $skipped[$i], $buffer);
    }
    return $buffer;
}

2 个答案:

答案 0 :(得分:2)

我使用的是脚本语言,我会使用多步骤方法。

  • 拉出NOSTRIP部分,保存到数组,然后用标记替换(###或其他)
  • 替换所有空格
  • 重新注入所有已保存的NOSTRIP片段

答案 1 :(得分:1)

我曾经创建了一组函数来减少html输出中的空白区域:

function minify($html) {
        if(empty($html)) {
                return $html;
        }
        $html = preg_replace('/^(.*)((<pre.*<\/pre>)(.*?))?$/Ues', "parse('$1').'$3'.minify('$4')", $html);
        return $html;
}

function parse($html) {
        var_dump('1'.$html);
        // Replace multiple spaces with a single space
        $html = preg_replace('/(\s+)/m', ' ', $html);
        // Remove spaces that are followed by either > or <
        $html = preg_replace('/ ([<>])/', '$1', $html);
        $html = str_replace('> ', '>', $html);
        return $html;
}

$html = minify($html);

您可能需要稍微修改一下以满足您的需求。