【问题标题】:Using Lookahead to match a string using a regular expression使用 Lookahead 使用正则表达式匹配字符串
【发布时间】:2010-09-26 00:36:53
【问题描述】:

我需要使用正则表达式匹配一个字符串 holiding html 以提取所有嵌套跨度,我假设我认为有一种方法可以使用正则表达式来做到这一点,但整个早上都没有成功。

所以对于一个示例输入字符串

<DIV id=c445c9c2-a02e-4cec-b254-c134adfa4192 style="BORDER-RIGHT: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BORDER-BOTTOM: #000000 1px solid; BACKGROUND-COLOR: #eeeeee">
<SPAN id=b8db8cd1-f600-448f-be26-2aa56ea09a9c>
<SPAN id=304ccd38-8161-4def-a557-1a048c963df4>
<IMG src="http://avis.co.uk/Assets/build/menu.gif">
</SPAN>
</SPAN>
<SPAN id=bc88c866-5370-4c72-990b-06fbe22038d5>
<SPAN id=55b88bbe-15ca-49c9-ad96-cecc6ca7004e>UK<BR></SPAN>
</SPAN>
<SPAN id=52bb62ca-8f0a-42f1-a13b-9b263225ff1d>
<SPAN id=0e1c3eb6-046d-4f07-96c1-d1ac099d5f1c>
<IMG src="http://avis.co.uk/Assets/build/menu.gif">
</SPAN>
</SPAN>
<SPAN id=4c29eef2-cd77-4d33-9828-e442685a25cb>
<SPAN id=0d5a266a-14ae-4a89-9263-9e0ab57f7ad2>Italy</SPAN>
</SPAN>
<SPAN id=f0a72eea-fddd-471e-89e6-56e9b9efbece>
<SPAN id=b7d9ada7-ade0-49fe-aa5f-270237e87c2b>
<IMG src="http://avis.co.uk/Assets/build/menu.gif">
</SPAN>
</SPAN>
<SPAN id=7604df94-34ba-4c89-bf11-125df01731ff>
<SPAN id=330d6429-4f1b-46a2-a485-9001e2c6b8c1>Netherlands</SPAN>
</SPAN>
<SPAN id=a18fb516-451e-4c32-ab31-3e3be29235f6>
<SPAN id=6c70238d-78f9-468f-bb8d-370fff13c909>
<IMG src="http://avis.co.uk/Assets/build/menu.gif">
</SPAN>
</SPAN>
<SPAN id=5a2465eb-b337-4f94-a4f8-6f5001dfbd75>
<SPAN id=47877a9e-a7d5-4f13-a41e-6948f899e385>Malta &amp; Gozo

我想获取每个外部跨度及其包含的跨度,因此在上面的文本中应该有八个结果

欣然接受任何帮助

【问题讨论】:

    标签: c# html regex


    【解决方案1】:

    试试这个:

    @"(?is)<SPAN\b[^>]*>\s*(<SPAN\b[^>]*>.*?</SPAN>)\s*</SPAN>"
    

    这与 PhiLho 的正则表达式基本相同,除了它允许两端的标签之间有空格。我还必须添加 SingleLine/DOTALL 修饰符以适应匹配文本中的行分隔符。我不知道这些更改中的任何一个是否真的有必要。 OP 发布的示例数据都在一行上,但 PhiLho 将其分解(从而破坏了他自己的正则表达式)。

    【讨论】:

      【解决方案2】:

      基本上,我同意上述建议,使用正则表达式解析 HTML 要求有一天会在奇怪的合法 HTML 结构上破坏代码(更不用说浏览器接受的格式错误的 HTML...)。找到并使用一个好的 HTML 解析器可以在很多方面获得回报...

      现在,我很务实(我无法抗拒一点正则表达式的挑战...),有时我会针对机器生成的 HTML 使用 RE(通常是导出功能),因为我知道我看到的结构不太可能改变,不像手工生成的页面,作者可以打错字...主要是为了快速修改,如果输出发生变化,我可以适应。

      在您的情况下,HTML 非常规则、线性且可预测,因此 RE 非常简单。我给出Java代码是因为我不懂C#,但适应应该是微不足道的。

      Pattern p = Pattern.compile("(<SPAN id.*?<SPAN id.*?</SPAN></SPAN>)");
      Matcher m = p.matcher(html);
      while (m.find())
      {
        System.out.println(m.group(1));
      }
      

      HTH。

      【讨论】:

        【解决方案3】:

        使用标准正则表达式实际上是不可能解决这个问题的,因为它们基本上在Chomsky hierarchy(有限状态自动机)中实现了类型 3 语法,而您至少需要一个类型 2 语法(某种堆栈或递归)来正确识别任意嵌套结构。

        但是,如果您限制最大可能的嵌套级别,那么它可能是可能的,但我仍然怀疑正则表达式是否是最佳解决方案。

        【讨论】:

        • .NET 的实现支持计数,因此可以匹配开始/结束标记等。但是对于任何超出简单匹配的真正解析器都是可行的方法。
        【解决方案4】:

        再次use an HTML parser 遍历 DOM:正则表达式永远不会强大到足以做到这一点。

        【讨论】:

        • regexHtmlParserQuestions++ ;-)
        • 显然它必须是:++regexHtmlParserQuestions++;
        猜你喜欢
        • 1970-01-01
        • 2023-01-30
        • 2012-11-29
        • 2020-11-04
        • 1970-01-01
        • 1970-01-01
        • 2020-06-10
        • 2022-10-01
        • 2014-11-26
        相关资源
        最近更新 更多