如何使用JavaScript匹配不在<a>及其href内的网页上的关键字?

use*_*080 5 html javascript regex

我正在搜索页面以查找特定关键字.这本身很容易.增加的复杂性是,如果它是<a>标记的一部分,我不想匹配此关键字.

例如

<p>Here is some example content that has a keyword in it. 
I want to match this keyword here but, i don't want to match 
the <a href="http://www.keyword.com">keyword</a> here.</p>
Run Code Online (Sandbox Code Playgroud)

如果您查看上面的示例内容,"关键字"一词会出现4次.我想它似乎与段落中第一个两次匹配,但我不希望匹配它时,它出现的部分href和作为的一部分<a>内容.

到目前为止,我已成功使用以下内容:

var tester = new RegExp("((?!<a.*?>)("+keyword+")(?!</a>))", 'ig');
Run Code Online (Sandbox Code Playgroud)

上面的问题是它仍然匹配关键字,如果它是的一部分href.

有任何想法吗?谢谢

Tim*_*ker 5

使用JavaScript正则表达式无法可靠地执行此操作.使用.NET正则表达式引擎是很难的,这是少数几个支持无限长的lookbehind断言的引擎之一,但是JavaScript根本不知道看后面的断言,所以你不能回头看看文本之前的内容你想要匹配.

因此,您应该使用DOM解析器(我确信精通JavaScript的人可以在这里建议一种实用的方法),或者阅读文本,删除所有<a>标签(如果你是正确的话,可以使用正则表达式勇敢的类型),然后在文本的其余部分搜索您的关键字.

编辑:

好吧,你可以使用一个肮脏的黑客.它不漂亮,如果你看看艾伦摩尔对你的问题的评论,你将能够想象这个正则表达式失败的多种方式,但它确实适用于你的例子:

/keyword(?!(?:(?!<a).)*</a)/
Run Code Online (Sandbox Code Playgroud)

它是如何工作的"?

keyword    # Match "keyword"
(?!        # but only if it is not possible to match the following regex in the text ahead:
 (?:       # - Match...
  (?!<a)   # -- unless it's the start of an <a> tag...
  .        # -- any character
 )*        # - any number of times
 </a>      # then match a closing <a> tag. 
)          # End of lookahead assertion.
Run Code Online (Sandbox Code Playgroud)

即使有了解释,这也很神秘.它本质上是做什么的:

  • 匹配"关键字"
  • 请注意</a>以下文字中没有结束
  • 除非首先是开头<a>标签.

因此,如果所有<a>标记都是正确平衡的,而不是嵌套的,在注释或脚本块中找不到,那么您可能只是侥幸逃脱它.