如果没有另一个特定单词,则替换特定单词的出现?

时间:2013-05-24 02:47:12

标签: php regex preg-replace preg-replace-callback negative-lookbehind

我有一些文字:

*open* blah blah blah blah blah *close* blah blah *open* blah blah *close* blah blah *close*

我想知道如何删除/替换*close*未出现的*open*出现的任何事件。

所以上面的文字会变成:

*open* blah blah blah blah blah *close* blah blah *open* blah blah *close* blah blah

我虽然可能在preg_replace中使用正则表达式 - 但我的正则表达式技巧不是那么强大?

<?php
$string = "*open* blah blah blah blah blah *close* blah blah *open* blah blah *close* blah blah *close*";

$string = preg_replace('#(?<!\*open\*)\*close\*#', '', $string); //this only works for immediate proceedings

echo($string);
?>

欢迎使用代码示例。

2 个答案:

答案 0 :(得分:1)

可以通过以下代码在没有正则表达式的情况下完成:

$openTag = '*open*';
$closeTag = '*close*';
$openTagLength = mb_strlen($openTag);
$closeTagLength = mb_strlen($closeTag);

$subj = '*open* blah blah blah blah blah *close* blah blah *open* blah blah *close* blah blah *close*';
$len = mb_strlen($subj);
$isOpened = false;
$res = '';
for ($i = 0; $i < $len; )
{
    if (mb_substr($subj, $i, $openTagLength) === $openTag) {
        // found open tag
        $res .= $openTag;
        $isOpened = true;
        $i += $openTagLength;
    } elseif (mb_substr($subj, $i, $closeTagLength) === $closeTag) {
        // found close tag
        if ($isOpened) {
            $res .= $closeTag;
        } // else skip
        $isOpened = false;
        $i += $closeTagLength;
    } else {
        // non-tag
        $res .= mb_substr($subj, $i, 1);
        $i++;
    }
}
echo $res;

答案 1 :(得分:0)

试试这个:

    $pattern = "/(\\*open\\*.*?\\*close\\*)/";
    $target = "*close* *close* *open* blah blah blah blah blah *close* blah blah *open* blah blah *close* blah blah *close* *close* *open* *open* *close* ";

    $prevMatchEndIndex = 0;
    $matches = array();
    $lastMatchEndIndex = 0;
    $resultParts = array();
    while(preg_match($pattern, $target, $matches, PREG_OFFSET_CAPTURE, $prevMatchEndIndex)) {
        $matchedString = $matches[0][0];
        $matchStartIndex = $matches[0][1];
        $matchEndIndex = $matchStartIndex + strlen($matchedString) + 1;

        $unmatchedString = substr($target, $prevMatchEndIndex, $matchStartIndex - $prevMatchEndIndex);

        $unmatchedString = preg_replace("/\\s*\\*close\\*\\s*/", " ", $unmatchedString);

        $resultParts[] = trim($unmatchedString);
        $resultParts[] = trim($matchedString);

        $prevMatchEndIndex = $matchEndIndex;
        $lastMatchEndIndex = $matchEndIndex;
    }

    $lastUnmatchedPart = substr($target, $lastMatchEndIndex);
    $lastUnmatchedPart = preg_replace("/\\s*\\*close\\*\\s*/", " ", $lastUnmatchedPart);
    $resultParts[] = $lastUnmatchedPart;    

    echo $target . "<br />";
    echo join($resultParts, " ");