html - 正规表达式匹配开放的标签(不包含XHTML自包含的标签)

  显示原文与译文双语对照的内容

我需要匹配所有这些开始标记:


<p>
<a href="foo">

但不是这些:


<br/>
<hr class="foo"/>

我想到了这个,并想确保我得到了正确的结果。 我只捕获 a-z


<([a-z]+) *[^/]*?>

我相信上面写着:

  • 找到一个 less-than,然后
  • 查找( 并捕获) a-z一次或者多次,然后
  • 查找零个或者多个空格,然后
  • 查找任何字符零次或者多次,贪婪,除 / 外,
  • 查找 greater-than

我有那个权利? 更重要的是你认为?

时间:

你不能解析 [X] HTML 因为 正规表达式 不能被解析。 正规表达式 不是可以用于正确解析HTML的工具。 就像我在这里的HTML-and-regex问题中多次回答的那样,正规表达式的使用将不允许你使用 HTML 。 正规表达式 是一个不足以理解HTML所使用的结构的工具。 HTML不是普通语言,因此不能被 正规表达式 解析。 正规表达式 查询没有将HTML分解为它的有意义的部分。 这么多次,但它并没有到达我。 即使是Perl使用的增强的不规则 正规表达式 也不能胜任解析HTML的任务。 你不会让我crack的。 HTML是一种复杂的语言,它不能被 正规表达式 解析。 甚至Jon飞碟不能用 正规表达式 解析 HTML 。 每次你想要解析HTML有了 正规表达式,unholy子virgins和俄罗斯黑客 pwn weeps血液,你的web应用程序的。 用 正规表达式 解析HTML将污染的灵魂带入生活领域。 HTML和 正规表达式 像爱,婚姻和仪式一样结合在一起。 <中心> 无法容纳它太晚了。 在相同的概念空间中,正规表达式 和HTML的力量会破坏你的思维,如同如此多的水 Putty 。 如果你解析HTML使用 正规表达式 你可以使他们( 它们在给他们及其blasphemous方式,这注定我们互相 inhuman toil取代代码中她的名字在基本多语言平面,叫他不能表达的。 为时已晚,为时已晚,我们无法保存尊敬的上帝帮助我们如何在这个灾难中幸存 使用 正规表达式 解析HTML已经注定了人类永恒的恐惧和安全漏洞 使用 rege 作为处理HTML的工具建立了一个 brea 这个世界之间的通道更多的损坏( glimp )rogrammer的意识 nto w orl 不断尖叫,他来了 pestilent sl他来了,他来了 es 不首先ssion解析 将 EXTI 他 inal snuf o 是他 s t 他得了严重的健忘症。es al 我的因素


是否尝试使用XML解析器?


版主 注。

这里贴子被锁定以防止对它的内容进行不适当的编辑。 这篇文章看起来完全像看起来一样- 它的内容没有问题。 请不要为我们的注意而标记它。

我认为这里的缺陷是HTML是一个语法类型 2语法( 上下文无关语法) 和 正规表达式 是一个乔姆斯基类型 3语法( 常规语法) 。 由于类型 2语法基本上比类型 3语法( 参见乔姆斯基层次结构 ) 复杂,所以你不能使它的工作。 但很多人会尝试,有些会声称成功,其他人会发现错误并完全搞乱你。

英镑免责声明: 如果有选项,请使用解析器。 也就是说。。

这是 正规表达式 我使用( ) 来匹配HTML标记: !


<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>

它可能不是完美的,但是我通过一个的HTML来运行这个代码。 注意,它甚至捕捉了一些奇怪的东西,比如 <a name="badgenerator"">,它显示在网络上。

我想,为了使它不匹配自己包含的标记,你可以使用 Kobi的负数:


<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/s*)>

或者如果没有的话就组合。

downvoters:,这是来自实际产品的代码。 我怀疑有人阅读这个页面会感觉到在HTML上使用regex是可以接受的。

要警告 要我选我就注意这 正规表达式 仍然在CDATA块,注释和脚本和样式元素的存在就崩溃了。 好消息是,你可以用 正规表达式 摆脱那些。。

不要听这些家伙。 确实可以解析context-free文法与 正规表达式,如果你把任务分成更小的块。 你的模式需要按照以下顺序进行:

  1. 解决停机问题。
  2. 正方形( 使用"标尺和指南针"这里方法的方法) 。
  3. 在 O(log n) 中解决旅行推销员问题。 它需要快速或者你的正规表达式 引擎将挂起。
  4. 结果将是相当大的,所以确保你有另外一个算法来压缩随机数据。
  5. 几乎那里- 只把整个东西除以零。 Easy-peasy 。

我还没有弄清楚最后一部分,但它不应该是硬的。 我的代码不断引发 CthulhuRlyehWgahnaglFhtagnException 最近,我正在设置一个空的catch 块,只使用这些块并继续解析。 我将用代码更新一旦我在墙上打开了这个陌生的门。 嗯~

皮埃尔。de Fermat也想出了如何做,但他所写的边距还不足以用于代码。

在 sed though,就可以解析 HTML.

  1. Turing.sed
  2. 编写HTML解析器( 作业)
  3. 利润 !

我同意解析XML和特别是 HTML的正确工具是解析器,而不是正则表达式引擎。 但是,就像其他人指出的,有时候使用 正规表达式 会更快,更容易,并且如果你知道数据格式,就会完成任务。

微软的有一个叫做小节 正规表达式的最佳实践在. NET 框架和专门谈到了考虑在输入源 [ing] 。

正规表达式 确实有限制,但你是否考虑过以下内容?

.NET 框架对于 正规表达式 来说是独一无二的,因为它支持平衡组定义

因此,我相信你可以使用 正规表达式 解析 XML 。 但是,请注意,它的必须是有效的XML ( 浏览器对HTML非常宽容,允许在 HTML 中使用糟糕的XML语法) 。 这是可能的,因为"平衡组定义"将允许正则表达式引擎作为 PDA 。

上文引用的文章引用:

.NET 正则表达式引擎

如上所述,正确平衡的构造不能由正则表达式描述。 但是,.NET 正则表达式引擎提供了一些构造,允许识别平衡结构。

  • (?<group>) - 使用名称组将捕获的结果推送到捕获堆栈。
  • (?<-group>) - 从捕获堆栈中弹出具有名称组的最多捕获。
  • (?(group)yes|no) - 如果存在同名组,则匹配yes是part部分,否则不匹配任何部件。

这些构造允许. NET 正则表达式模拟受限制的PDA,从而允许简单的堆栈操作版本: push,pop和 empty 。简单操作几乎等同于递增,递减和比较零。 这允许. NET 正则表达式引擎识别context-free语言的子集,特别是只需要一个简单计数器的子集。 这又允许非传统的.NET 正规表达式 识别单独平衡的构造。

请考虑以下正则表达式:


(?=<uls+id="matchMe"s+type="square"s*>)
(?>
 <!--. *? --> |
 <[^>]*/> |
 (?<opentag><(?!/)[^>]*[^/]>) |
 (?<-opentag></[^>]*[^/]>) |
 [^<>]*
)*
(?(opentag)(?!))

使用以下标志:

  • 单行
  • IgnorePatternWhitespace ( 如果折叠 正规表达式 并删除所有空白,则不需要)
  • IgnoreCase ( 不需要)

正则表达式解释( 内联)


(?=<uls+id="matchMe"s+type="square"s*>) # match start with <ul id="matchMe"...
(?> # atomic group/don't backtrack (faster)
 <!--. *? --> | # match xml/html comment
 <[^>]*/> | # self closing tag
 (?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
 (?<-opentag></[^>]*[^/]>) | # pop closing xml tag
 [^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack

你可以在处尝试一个更好的.NET 正则表达式测试器

我使用了以下示例源:


<html>
<body>
<div>
 <br/>
 <ul id="matchMe" type="square">
 <li>stuff...</li>
 <li>more stuff</li>
 <li>
 <div>
 <span>still more</span>
 <ul>
 <li>Another &gt;ul&lt;, oh my!</li>
 <li>...</li>
 </ul>
 </div>
 </li>
 </ul>
</div>
</body>
</html>

找到了匹配:


 <ul id="matchMe" type="square">
 <li>stuff...</li>
 <li>more stuff</li>
 <li>
 <div>
 <span>still more</span>
 <ul>
 <li>Another &gt;ul&lt;, oh my!</li>
 <li>...</li>
 </ul>
 </div>
 </li>
 </ul>

虽然它实际上是这样出来的:


<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another &gt;ul&lt;, oh my!</li> <li>...</li> </ul> </div> </li> </ul>

最后,我非常喜欢atwood的Jeff文章: 解析 Html Cthulhu方式。 有趣的是,它引用了这个问题的答案,目前有超过 4 k的投票。

尽管你不能用regex解析HTML的答案是正确的,但它们并不适用。 OP只需要解析一个带有regex的HTML标记,它可以通过正则表达式完成。

建议的正规表达式 错误:


<([a-z]+) *[^/]*?>

如果你向 正规表达式 中添加一些东西,通过回溯可以强制匹配像 <a>> 这样的愚蠢事物,[^/] 太宽容了。 还要注意,<space>*[^/]* 是多余的,因为 [^/]* 也可以匹配空格。

我的建议是


<([a-z]+)[^>]*(?<!/)>

(?<.. . ) 是( 在Perl正则表达式中)的负数 look-behind 。! 它读取"一个 <,然后是一个单词,然后是不是>的,最后一个可能不是/,后面是>"。

注意,这允许像 <a/> ( 就像原来的正规表达式 ) 这样的东西,所以如果你想要更多的限制,你需要构建一个 正规表达式 来匹配由空格分隔的属性对。

...