正则表达式挑战:仅在<a href=""> tag</a>之外匹配短语

时间:2009-10-13 01:31:08

标签: regex asp-classic vbscript

我正在努力改进自定义CMS中的词汇表功能,该CMS使用VBScript代码在IIS上运行经典ASP(ASP 3.0)。我很难接受一个我无法解决的正则表达式挑战。

以下是当前代码:

     If InStr(ART_ArticleBody, "href") = False then
   sql="SELECT URL, Term, RegX FROM GLOSSARYDB;"
   Set rsGlossary = Server.CreateObject("ADODB.Recordset")
   rsGlossary.open sql, strSQLConn
   Set RegExObject = New RegExp
      While Not rsGlossary.EOF
      URL = rsGlossary("URL")
      Phrase = rsGlossary("RegX")
      With RegExObject
     .Pattern = Phrase
     .IgnoreCase = true
     .Global = false
      End With
      set expressionmatch = RegExObject.Execute(ART_ArticleBody)
      if expressionmatch.count > 0 then
      For Each expressionmatched in expressionmatch
      RegExObject.Pattern = Phrase
      URL = "<a href=" & URL & ">"& expressionmatched.Value & "</a>"
     ART_ArticleBody = RegExObject.Replace(ART_ArticleBody, URL)
      next
      end if
      rsGlossary.movenext
      wend
      rsGlossary.movefirst
   Set RegExObject = nothing
  end if

不像在上面的代码那样在任何有href的文章中跳过词汇表链接,我想改变代码来处理每篇文章,但是RegEx模式避免匹配如果匹配位于标记内,则在词汇表条目上。

例如,下面的斜体字是我的数据库中此正则表达式条目的测试示例:ROI|return on investment|investment return

以下是使用词汇表术语的链接:<a href="ROI.htm">Info on return on investment</a>. 现在,这是纯文本中的术语表术语,而不是链接内部:return on investment。 我们希望找到匹配的第三个实例,但找不到前两个,因为它们都在HTML链接中。

在上面的文字中,如果我正在处理词汇表条目“ROI |投资回报|投资回报”的文章,我不想匹配第一次或第二次匹配,因为它们在一个标签中。我需要正则表达式模式来跳过这些匹配,并且只匹配任何不在标记内的匹配。

对此的任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:1)

正如他们所说,这个问题在当前状态下是“非平凡的”。但是,如果您可以修改系统以输出更多语义标记,则可以使事情变得更加容易:

<a href="ROI.htm">undesired tag match</a>
This is <span class="tag">a tag</span>

在这种情况下,您只需搜索:

(?<=<span class=\"tag\">)(phrase1|phrase2|phrase3)(?=</span>)

或者更健壮的东西

(?<=<span class=\"tag\">).+?(?=</span>)

通过这种方式,您可以轻松将搜索重点放在特定<span>内的数据中,并将其他所有内容都放在一边。

答案 1 :(得分:1)

试试这个正则表达式:

<a\b[^<>]*>[\s\S]*?</a>|(ROI|return on investment|investment return)

这匹配HTML锚点或您正在寻找的任何术语。这些术语被捕获到组号1中。因此,在您的VBScript代码中,检查第一个捕获组是否与任何内容匹配,并且您在&lt; a&gt;之外获得了一个关键字。标签

如果你嵌套了&lt; a&gt;这个正则表达式确实无法正常工作标签。这应该不是问题,因为锚通常不会彼此嵌套。如果它是一个问题,你无法使用VBScript / JavaScript正则表达式解决它。如果你有&lt; a&gt;正则表达式也将无法正常工作缺少结束标记的标记。如果你想考虑到这一点,试试这个正则表达式:

<a\b[^<>]*>(?:(?:(?!<a\b)[\s\S])*?</a>)?|(ROI|return on investment|investment return)

答案 2 :(得分:0)

你无法解决它,因为它无法完成,至少不具备100%的可靠性。 HTML在正则表达式意义上不是“常规”语言。就像俗话说的那样,当你有一把锤子时,一切都开始像钉子一样。正则表达式有一些不擅长的东西。这是其中之一。

大多数语言都有某种形式的HTML解析库作为标准或易于获得。使用那些。这就是他们的目的。

答案 3 :(得分:0)

通常,您不能使用正则表达式来识别任意嵌套的构造(例如括号分隔的HTML标记)。如果你已经解决了这个问题,那么就会有很多数学家排队等待它。 :)

话虽如此,.NET确实提供了对正则表达式的扩展,允许我刚才所说的不可能,并且 - 甚至更好! - 可用的“掌握正则表达式”的示例章节{{3}碰巧覆盖了这个功能。

答案 4 :(得分:0)

(accounts receivable|A/R)(?!((?!</?a\b).)*</a)

(phrase1|phrase2|phrase3)(?!((?!</?a\b).)*</a)

上述方法似乎有效,至少在我的RegexBuddy软件中是这样。我自己没弄明白。得到了一位大师的帮助。是时候在我的ASP代码中测试它了。感谢所有提供意见的人。我确信我没有描述我需要的东西,以便你提出上述解决方案。 Mea culpa。