【问题标题】:How do I find a HTML div contains specific text after a text prefix?如何在文本前缀后找到包含特定文本的 HTML div?
【发布时间】:2011-03-26 07:18:46
【问题描述】:

我有以下字符串:

<div> text0 </div> prefix <div> text1 <strong>text2</strong> text3 </div> text4

并想知道它是否包含 text3 在前缀后面的 div 中:

prefix<div>...text3...</div>

但我不知道如何为此制作正则表达式,因为我不能使用[^<]+,因为 div 可以在里面包含strong 标签。

请帮忙

编辑:

  1. 前缀后的div标签保证不嵌套
  2. 语言是 C#
  3. Text4 很长,所以 regex 一定不要在关闭 div 后查看

EDIT2:我不想使用 html 解析器,它可以通过 Regex 轻松(并且更快)实现。 HTML 很简单:标签中没有属性;没有嵌套 div。在我的情况下,即使有 % 的错误答案也是可以接受的。

【问题讨论】:

  • 您不能(可靠地)为此使用正则表达式,因为正如您所指出的,正则表达式不处理非正则语言功能,例如 HTML 的嵌套/等。 您需要使用 HTML DOM 解析器 - 您尝试使用哪种语言?
  • 你可能想了解jquery
  • 什么语言?不同的语言支持不同的 RegEx 功能,并且它们相同。即使 RegEx 是错误的解决方案,推荐一个好的解决方案也需要了解您使用的语言。
  • @Peter Boughton:如果有人问这个问题,那应该是一个自动答案:)
  • Poma,对于 C#,看看 HtmlAgilityPack - htmlagilitypack.codeplex.com

标签: c# regex html-parsing html-agility-pack


【解决方案1】:

如果你关闭“贪婪”选项,你应该可以使用prefix<div>.*text3.*</div> 之类的东西。 (如果允许<div> 有属性,请改用prefix<div[^>]*>.*text3.*</div>。)

可以对此进行大量改进,以考虑不寻常的间距、引号内的>s、引号内的</div>等。

prefix<div>...<div></div>text3</div> 这样的模式会更难。您可能必须捕获所有出现的 div 标记,以便计算在给定时间打开了多少 div 标记。

编辑:糟糕,关闭贪婪选项并不总是会给出正确的结果,即使在上述示例之外的示例中也是如此。最好只捕获所有出现的div 标签并从那里开始。正如 Peter 上面提到的,HTML 不是 regular language,因此您不能使用正则表达式来做任何您想做的事情。

【讨论】:

    【解决方案2】:

    这是我的新正则表达式:

    prefix<div>([^<]*<(?!/div>))*[^<]*text3([^<]*<(?!/div>))*[^<]*</div>

    似乎工作正常。

    【讨论】:

      【解决方案3】:

      对于 C# + HtmlAgilityPack,您可以执行以下操作:

      InputString = Regex.Replace(InputString,"^(?:[^<]+?|<[^>]*>)*?prefix","");
      
      HtmlDocument doc = new HtmlDocument();
      
      doc.LoadHtml(InputString);
      
      HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[contains('text3')]");
      

      去除前缀仍然不是处理它的好方法。理想情况下,您会使用 HtmlAgilityPack 来查找 prefix 在 DOM 中出现的位置,将其翻译以提供字符串中的位置,然后执行 substring(pos,len) (或等效项)以仅查看相关文本(您也可以避免使用类似的方法查看 text4)。
      恐怕我现在无法将所有这些都翻译成代码。希望其他人可以提供帮助。


      (原始答案,在提供额外细节之前)
      这是一个 JavaScript + jQuery 解决方案:
      var InputString = '<div>text0 </div> prefix <div>text1 <strong>text2</strong> text3 </div> text4';
      
      InputString = InputString.replace(/^.*?prefix/,'');
      
      var MatchingDivs = jQuery('div:contains(text3)','<div>'+InputString+'</div>')
      
      console.log(MatchingDivs.get());
      

      这利用了 jQuery 接受 context as second argument 的能力(尽管看起来这需要被包裹在 div 标记中才能真正起作用)。

      【讨论】:

      • prefix 拆分然后尝试解析生成的子字符串之一也可能导致解析错误,如果前缀出现在标签中。 (不过,我没有使用过 jQuery,所以我不知道它在这种情况下会如何表现。)
      • 是的,那一点当然不是很好,但是我的大脑还不够清醒,无法想出一个合适的解决方案。 :( 我已经通过切换到替换稍微改进了它。
      猜你喜欢
      • 2010-10-11
      • 2019-05-05
      • 1970-01-01
      • 2017-01-24
      • 2018-03-29
      • 2014-06-01
      • 2013-06-02
      • 2018-01-14
      相关资源
      最近更新 更多