正则表达式只在两个字符串之外发生时才替换文本?

时间:2008-11-19 11:49:06

标签: php regex

我想将“& gt”替换为“>”和“< lt”与“<”但只有当它们出现在“< pre>”之外时和“< / pre>”。这可能吗?

$newText = preg_replace('&gt', '>', $text);

我将在PHP中使用preg_replace,如上所述。

3 个答案:

答案 0 :(得分:3)

这不是一个真正的答案,因为你要求一个正则表达式,但我只是写了一个非常脏的函数来执行它:

<?php

$html = ' <pre>hello &gt; &lt;</pre>
            &gt; &lt;
            <pre></pre>';


function stringReplaceThing($str) {
    $offset = 0;
    $num = 0;
    $preContents = array();
    $length = strlen($str);

    //copy string so can maintain offsets/positions in the first string after replacements are made
    $str2=$str;

    //get next position of <pre> tag
    while (false !== ($startPos = stripos($str, '<pre>', $offset))) {
        //the end of the opening <pre> tag
        $startPos += 5;

        //try to get closing tag
        $endPos = stripos($str, '</pre>', $startPos);

        if ($endPos === false) {
            die('unclosed pre tag..');
        }

        $stringWithinPreTags = substr($str, $startPos, $endPos - $startPos);
        //replace string within tags with some sort of token
        if (strlen($stringWithinPreTags)) {
            $token = "!!T{$num}!!";
            $str2 = str_replace($stringWithinPreTags, $token, $str2);
            $preContents[$token] = $stringWithinPreTags;
            $num++;
        }

        $offset = $endPos + 5;
    }

    //do the actual replacement
    $str2 = str_replace(array('&gt;', '&lt;'), array('>', '<'), $str2);

    //put the contents of <pre></pre> blocks back in
    $str2 = str_replace(array_keys($preContents), array_values($preContents), $str2);
    return $str2;
}


print stringReplaceThing($html);

答案 1 :(得分:2)

如果你想用正则表达式做这个,那么诀窍就是让你的正则表达式匹配你不想要替换的东西以及要替换的东西,并根据匹配的内容动态计算替换

$new_text = preg_replace_callback('%&lt;|&gt;|<pre>.*?</pre>%si', compute_replacement, $text);

function compute_replacement($groups) {
    if ($groups[0] == '&lt;') {
      return '<';
    } elseif ($groups[1] == '&gt;') {
      return '>';
    } else {
      return $groups[0];
    }
}

答案 2 :(得分:0)

我不确定PHP的正则表达式引擎是否会产生负面外观,但这就是你感兴趣的内容。其他语言中的正则表达式如下所示:

/(?<!(<pre>[^(<\/pre>)]*))XXX(?!(.*<\/pre>))/

(吸气 - 我认为我有这个权利)

其中XXX是您的模式“&lt;”或“&gt;”

NB。它可能还有一个更简单的模式