想要一个匹配>的正则表达式char不包含在任何标记中

时间:2018-03-27 05:24:05

标签: php regex tags

我想要一个匹配'>'的正则表达式文本中的字母不应与标记中的>匹配

例如 -

"<span>some >text< again some<some tag></some tag>vfs>vf</span>"

应匹配 - <span>some >text< again some<some tag></some tag>vfs>vf</span>
.............................................. | ... .................................................. ......... |

|表示要匹配的>

作为参考,我准备了一个正则表达式,它对<

做同样的事情

这是我的正则表达式 - "/(?!<[^<>]*>)**<**/"(此处'&lt;'只是粗体显示在这里)

提前致谢!

1 个答案:

答案 0 :(得分:0)

如果您的要求很简单 - 不包括引用或转义的尖括号,也不包括嵌套的尖括号对,则查找STARTING不匹配括号的问题是以开括号开头的字符串的第一个位置,不包含内部括号,以另一个开括号或字符串末尾结束。

在正则表达式中,这将是:

/(<)[^<>]*(?:$|<)/

因为您想捕获所有这些,并且将使用preg_match_all,您需要添加前瞻以捕获重叠匹配:

/(?=(<)[^<>]*(?:$|<))/

类似地,不匹配的右括号问题简化为字符串的最后一个字符,以字符串的开头或闭括号开头,以close括号结尾,中间没有括号。添加前瞻,你会得到:

/(?=(?:^|>)[^<>]*(>))/

我在测试字符串中添加了几个额外的括号,以确保我们捕获结束和重叠的情况,以及替换示例:

<?php
// Left angle brackets
$x = "<span>some >text< again<< some<some tag><</some tag>vfs>vf</span><<";
$y = preg_match_all('/(?=(<)[^<>]*(?:$|<))/', $x, $match, PREG_OFFSET_CAPTURE);
echo "Test: '{$x}'\n";
echo "Repl: '" . locate_replace($x, $match[1], '\<') . "'\n";
echo "There are {$y} extra left angle brackets at character positions:\n";
echo "  " . implode(", ", array_column($match[1], 1)) . "\n\n";

// Right angle brackets

$x = "abc><span>some >text< again some<some tag></some tag>vfs>>vf</span>";
$y = preg_match_all('/(?=(?:^|>)[^<>]*(>))/', $x, $match, PREG_OFFSET_CAPTURE);
echo "Test: '{$x}'\n";
echo "Repl: '" . locate_replace($x, $match[1], '\>') . "'\n";
echo "There are {$y} extra right angle brackets at character positions:\n";
echo "  " . implode(", ", array_column($match[1], 1)) . "\n";

function locate_replace($x, $match_oc, $repl) {
    while ($mt = array_pop($match_oc)) {
        $sloc = $mt[1];
        $eloc = $sloc + strlen($mt[0]);
        $x = substr($x, 0, $sloc) . $repl . substr($x, $eloc);
    }
    return $x;
}
?>

这会产生:

Test: '<span>some >text< again<< some<some tag><</some tag>vfs>vf</span><<'
Repl: '<span>some >text\< again\<\< some<some tag>\<</some tag>vfs>vf</span>\<\<'
There are 6 extra left angle brackets at character positions:
  16, 23, 24, 40, 65, 66

Test: 'abc><span>some >text< again some<some tag></some tag>vfs>>vf</span>'
Repl: 'abc\><span>some \>text< again some<some tag></some tag>vfs\>\>vf</span>'
There are 4 extra right angle brackets at character positions:
  3, 15, 56, 57