不包含特定字符串的正则表达式模式

4
这个问题已经在这里提出过了,但是提问者只得到了一个2个字符的答案。我重复他的基本问题:

通常,有没有一种方法可以像使用 [^a] 表示不包含字符一样来表示不包含字符串?

我想创建一个正则表达式,它匹配两个结束字符串和中间的所有内容,但仅当未发现给定字符串的其他出现时才匹配。但我最满意的是对上述问题的一般回答。

例子:

字符串是"<script>""</script>"

应该匹配:

"<script> something something </script>"

但不是

"<script> something <script> something something </script>"

请看这个问题:链接 - YOU
1
你正在尝试解析HTML吗?如果是的话,最好使用HTML解析器。 - Gumbo
是的,我没有找到。 它始于匹配一行,我肯定跳过了阅读其余部分 ;) - naugtur
如果您正在尝试过滤或清理HTML,则仍应使用解析器。 - Otto Allmendinger
1
@naugtur:如果你要删除的内容是HTML,最好使用解析器。市面上有一些JS HTML解析器 http://www.google.com/search?q=javascript+html+parser - Otto Allmendinger
显示剩余7条评论
3个回答

4

你有没有看过我对那个问题的答案?它提供了一个更普遍的解决方案。在你的情况下,它会像这样:

(?s)<script>(?:(?!</?script>).)*</script>

换句话说:先匹配开头序列,然后逐个匹配字符,在确保不是关闭序列的开头之后;最后匹配关闭序列。

我仍然不理解括号中发生了什么,也不知道为什么它们不匹配,但我会弄清楚的。谢谢 - naugtur
1
这个正则表达式有不平衡的括号。当我修复表达式时,它既不匹配字符串中的任何一个。 - Otto Allmendinger
我应该测试它的,即使在之前我已经发布了十几次。谢谢,Bart。 - Alan Moore
负向先行断言应该针对<script>而不是</script> - Otto Allmendinger
实际上,如果您认为标签有任何意义的话,那么这是用于</script>的。这个例子相当愚蠢;) 在使用它时,我改变的第一件事是寻找!</script>而不是!<script>。如果有人嵌套了一个脚本,最好删除所有标题标签。 - naugtur
显示剩余3条评论

1

你问题的正确表达方式是:

"^<script>((?!<script>).)*</script>$"

这个不应该用于HTML操作。它不能解决像

这样的情况。
<script> foo <script type="javascript"> bar </script>

还有许多其他的情况需要解析器来正确处理。

匹配以 START 开头,以 END 结尾,但中间不包含特定字符序列 foobar 的字符串的更一般表达式为:

"^START((?!foobar).)*END$"

我进行了一些调整,输入有点不同,因此无需担心HTML内容。 - naugtur

1

使用负向先行断言。先行断言提供零宽度匹配-这意味着它们不会在源字符串中消耗任何字符。

var s1 = "some long string with the CENSORED word";
var s2 = "some long string without that word";
console.log(s1.match(/^(?!.*CENSORED).*$/));//no match
console.log(s2.match(/^(?!.*CENSORED).*$/));//matches the whole string

负向先行断言的语法是(?!REGEX)。它搜索REGEX,如果找到匹配项,则返回false。正向先行断言(?=REGEX)如果找到匹配项,则返回true。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接