Regex 正则表达式挑战:仅当在<;a href>;标签

Regex 正则表达式挑战:仅当在<;a href>;标签,regex,asp-classic,vbscript,Regex,Asp Classic,Vbscript,我正在用VBScript代码在IIS上运行经典ASP(ASP 3.0)的自定义CMS中改进术语表功能。我被一个无法解决的正则表达式挑战难住了 以下是当前代码: If InStr(ART_ArticleBody, "href") = False then sql="SELECT URL, Term, RegX FROM GLOSSARYDB;" Set rsGlossary = Server.CreateObject("ADODB.Recordset") rsGloss

我正在用VBScript代码在IIS上运行经典ASP(ASP 3.0)的自定义CMS中改进术语表功能。我被一个无法解决的正则表达式挑战难住了

以下是当前代码:

     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
如果InStr(ART_ArticleBody,“href”)=False则
sql=“从GLOSSARYDB中选择URL、术语、RegX;”
Set rsGlossary=Server.CreateObject(“ADODB.Recordset”)
rsGlossary.opensql,strSQLConn
Set RegExObject=New RegExp
而不是rsGlossary.EOF
URL=rsGlossary(“URL”)
短语=rsGlossary(“RegX”)
使用RegExObject
.模式=短语
.IgnoreCase=true
.Global=false
以
set expressionmatch=RegExObject.Execute(ART_ArticleBody)
如果expressionmatch.count>0,则
对于expressionmatch中匹配的每个表达式
RegExObject.Pattern=短语
URL=“”
ART_ArticleBody=RegExObject.Replace(ART_ArticleBody,URL)
下一个
如果结束
rsGlossary.movenext
温德
rsGlossary.movefirst
设置RegExObject=nothing
如果结束
我不想像上面的代码那样跳过在任何包含href的文章中添加词汇表链接,而是希望更改代码以处理每一篇文章,但如果匹配项位于a标记内,则在词汇表条目上使用RegEx模式避免匹配

例如,以下斜体字是my DB中此正则表达式条目的测试示例:
ROI |投资回报|投资回报

这里有一个使用术语表术语的链接:
现在,这里是纯文本的术语表,而不是在链接中:
投资回报
。 我们想找到匹配的第三个实例,但找不到前两个,因为它们都在HTML链接中

在上面的文本中,如果我正在处理术语表条目“ROI |投资回报|投资回报”的文章,我不想匹配第一次或第二次出现的匹配,因为它们位于a标记中。我需要正则表达式模式跳过这些匹配,只匹配不在a标记内的任何匹配


在此方面的任何帮助都将不胜感激

你无法解决它,因为它无法完成,至少不能以100%的可靠性完成。HTML不是正则表达式意义上的“正则”语言。正如俗话所说,当你有一把锤子时,一切看起来都像钉子。有些事情正则表达式并不擅长。这是其中之一


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

一般来说,您不能使用正则表达式来识别任意嵌套的构造(例如以括号分隔的HTML标记)。如果你已经解决了这个问题,就会有很多数学家排队等着听你讲课


话虽如此,.NET确实提供了正则表达式的扩展,允许我刚才所说的是不可能的,甚至更好--《掌握正则表达式》的范例章节恰好涵盖了这一特性。

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

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

这是一个标签
在这种情况下,您只需搜索:

(?<=<span class=\"tag\">)(phrase1|phrase2|phrase3)(?=</span>)
(?
(应收账款|应收)(?!(?!试试这个正则表达式:

<a\b[^<>]*>[\s\S]*?</a>|(ROI|return on investment|investment return)
<a\b[^<>]*>(?:(?:(?!<a\b)[\s\S])*?</a>)?|(ROI|return on investment|investment return)
[\s\s]*?|(投资回报率|投资回报率|)
这与HTML锚或您要查找的任何术语相匹配。这些术语被捕获到组号1中。因此,在VBScript代码中,检查第一个捕获组是否匹配任何内容,并且您的一个关键字位于标记之外

如果您有嵌套的标记,则此正则表达式确实无法正常工作。这应该不是问题,因为锚点通常不会嵌套在彼此内部。如果出现问题,则无法使用VBScript/JavaScript正则表达式解决。如果您有缺少结束标记的标记,则正则表达式也无法正常工作。如果您希望考虑到这一点,请尝试以下正则表达式:

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

(?:(?:(?!因此,给定一组可能的短语,您希望找到它们中任何一个不在
范围内的所有实例?因此,例如,我希望正则表达式与以下内容不匹配:tag此问题是关于ASP Classic的my database的,因此我可以完全控制标记。我可以确保每一个都按照您上面所写的方式编写。因此,我n place,有没有可能用否定的lookaheads或lookbehinds来做这件事?Rex,如果我理解你的意思,你是说如果我只是用标签预先标记我所有的词汇表单词,那么就很容易找到它们。虽然我很感谢你的反馈,但这不是我想要做的。我正在尝试在t之前修改文章文本o为其提供服务,使术语表数据库中定义的术语表条目显示为链接。如果我愿意按照您的建议预处理这些文章并添加span标记,那么我最好只对术语表条目的链接进行硬编码。@kgaebler确实,您也可以!您将数据的低保真度副本存储为master和试图在提取时重建更高保真的版本。这是一个失败的游戏,正如你从这里的其他答案中所看到的。这很公平。我想你是说,将文章存储在带有HTML标记而不是其他语义标记的数据库中从一开始就注定了我的失败。我认为我没有足够的智慧来更改数据库到一种新的语义标记语言而不是HTML。所以,我想在我的循环中,我会检查例如tag。这是一个黑客,但我认为它可能会工作。谢谢你的帮助和大脑食物。天哪。真的是Jan Goyvaerts吗?太酷了。老兄,RegexBuddy rocks。谢谢你的帮助。我会尝试一下。我真的很喜欢这个技术。所以你把你想要的东西放进去了t在o上的parens中找到