我需要匹配所有这些开始标签:
<p>
<a href="foo">
但不是这些:
<br />
<hr class="foo" />
我想出了这个,想确保我做对了。我只是捕捉到a-z
。
<([a-z]+) *[^/]*?>
我相信它说:
- 找到一个小于,然后
- 查找(并捕获)az一次或多次,然后
- 找到零个或多个空格,然后
- 找到零次或多次贪婪的字符,除了
/
,然后 - 寻找大于
我有那个权利吗?更重要的是,您怎么看?
我需要匹配所有这些开始标签:
<p>
<a href="foo">
但不是这些:
<br />
<hr class="foo" />
我想出了这个,想确保我做对了。我只是捕捉到a-z
。
<([a-z]+) *[^/]*?>
我相信它说:
/
,然后我有那个权利吗?更重要的是,您怎么看?
在我看来,您正在尝试匹配结尾不带“ /”的标签。尝试这个:
<([a-zA-Z][a-zA-Z0-9]*)[^>]*(?<!/)>
如果您只是想查找这些标签(没有解析的野心),请尝试以下正则表达式:
/<[^/]*?>/g
我在30秒内编写了它,并在此处进行了测试:http: //gskinner.com/RegExr/
它与您提到的标签类型匹配,而忽略了您想忽略的标签类型。
<\s*(\w+)[^/>]*>
零件说明:
<
:起始字符
\s*
:标记名称前可能有空格(难看但可行)。
(\w+)
:标签可以包含字母和数字(h1)。好吧,\w
也匹配“ _”,但是我猜并没有伤害。如果好奇,请改用([a-zA-Z0-9] +)。
[^/>]*
:除了东西>
和/
直至收盘>
>
:关闭 >
对于那些低估正则表达式的人来说,它们仅与正则语言一样强大:
可以将非常规的,甚至不是上下文无关的n ba n ba n与^(a+)b\1b\1$
反引用FTW!
关于用于解析(x)HTML的RegExp方法的问题,对于所有谈到某些限制的人的答案是:您没有受过足够的训练来统治这种强大武器的力量,因为NOBODY在这里谈到了递归。
一位与RegExp无关的同事通知了我这个讨论,这肯定不是网络上有关这个古老而又热门话题的第一个讨论。
阅读了一些帖子之后,我要做的第一件事是在该线程中寻找“?R”字符串。第二个是搜索“递归”。
不,圣牛,没有找到匹配的东西。
由于没有人提到解析器所基于的主要机制,所以我很快意识到没人明白这一点。
如果(x)HTML解析器需要递归,则没有递归的RegExp解析器不足以实现此目的。这是一个简单的构造。
在正则表达式的黑色艺术是难以掌握,所以也许有,我们离开了,而试图和测试我们的个人解决方案捕获整个网络中,一方面进一步的可能性......好吧,我相信它:)
这是魔术图案:
$pattern = "/<([\w]+)([^>]*?)(([\s]*\/>)|(>((([^<]*?|<\!\-\-.*?\-\->)|(?R))*)<\/\\1[\s]*>))/s";
去尝试一下。
它以PHP字符串编写,因此“ s”修饰符使类包含换行符。
这是我在一月份写的PHP手册的示例注释:参考
(请注意,在该注释中,我错误地使用了“ m”修饰符;尽管未使用^或$定位符,但它已被RegExp引擎丢弃,但应将其删除)。
现在,我们可以从更明智的角度讨论此方法的局限性:
Anyhow it is only a RegExp pattern, but it discloses the possibility to develop of a lot of powerful implementations.
I wrote this pattern to power the recursive descent parser of a template engine I built in my framework, and performances are really great, both in execution times or in memory usage (nothing to do with other template engines which use the same syntax).
正如许多人已经指出的那样,HTML不是一种常规语言,因此很难解析。我的解决方案是使用整洁的程序将其转换为常规语言,然后使用XML解析器使用结果。为此有很多不错的选择。我的程序是使用Java和jtidy库编写的,将HTML转换为XML,然后通过Jaxen将xpath转换为结果。
这是一个基于PHP的解析器,它使用一些不合常规的正则表达式来解析HTML。作为该项目的作者,我可以告诉您可以使用正则表达式解析HTML,但是效率不高。如果您需要服务器端解决方案(就像我为wp-Typography WordPress插件所做的那样),则可以使用。
我以前使用过一个名为HTMLParser的开源工具。它旨在以各种方式解析HTML,并且很好地达到了目的。它可以将HTML解析为不同的treenode,并且您可以轻松地使用其API从节点中获取属性。检查一下,看看是否可以帮到您。
如果您需要PHP:
在PHP DOM 功能,除非它是格式正确的XML将无法正常工作。无论它们对全人类的使用有多好。
simplehtmldom很好,但是我发现它有点bug,而且它的内存占用很大[将在大页面上崩溃。]
我从未使用过querypath,因此无法评论其有用性。
另一个可以尝试的是我的DOMParser,它对资源非常少,并且我已经很开心地使用了一段时间。简单易学,功能强大。
对于Python和Java,发布了类似的链接。
对于下注者-我仅在XML解析器证明无法承受实际使用时编写类。宗教否决只会阻止发布有用的答案-请使问题保持在问题的角度之内。
您要第一个>
不带/
。看这里了解如何做到这一点的详细信息。这被称为否定性回溯。
但是,<bar/></foo>
该示例的简单实现最终将在此示例文档中匹配
<foo><bar/></foo>
您能否提供更多有关您要解决的问题的信息?您是否以编程方式遍历标签?
尝试:
<([^\s]+)(\s[^>]*?)?(?<!/)>
它与您的相似,但是最后一个>
不能在斜杠之后,并且也可以接受h1
。
我不知道您对此有确切的需求,但是如果您还使用.NET,则不能使用HTML Agility Pack吗?
摘抄:
它是一个.NET代码库,可让您解析“网络外” HTML文件。解析器对“真实世界”格式的HTML非常宽容。
W3C以伪正则表达式形式解释了解析:
W3C Link
遵循了var链接QName
,S
以及Attribute
获得更清晰的画面。
基于此,您可以创建一个很好的正则表达式来处理诸如剥离标签之类的事情。
中国古代的战略家,一般哲学家孙子说:
据说,如果您认识自己的敌人并认识自己,那么您就可以赢得一百场战斗,而不会遭受任何损失。如果您只了解自己而不是对手,那么您可能会赢或输。如果您既不认识自己,也不认识敌人,那么您将永远危害自己。
在这种情况下,您的敌人是HTML,而您本人或正则表达式。您甚至可能是使用不规则正则表达式的Perl。懂HTML。认识你自己。
我编写了一个描述HTML本质的句。
HTML has
complexity exceeding
regular language.
我还撰写了一个句,描述了Perl中正则表达式的性质。
The regex you seek
is defined within the phrase
<([a-zA-Z]+)(?:[^>]*[^/]*)?>
虽然您无法使用正则表达式解析HTML的答案是正确的,但它们不适用于此处。OP只想用正则表达式解析一个HTML标记,而这可以用正则表达式来完成。
建议的正则表达式是错误的,但是:
<([a-z]+) *[^/]*?>
如果您向正则表达式添加内容,则可以通过回溯将其强制匹配诸如之类的愚蠢内容<a >>
,[^/]
这太宽松了。另请注意,这<space>*[^/]*
是多余的,因为[^/]*
还可匹配空格。
我的建议是
<([a-z]+)[^>]*(?<!/)>
(?<! ... )
(在Perl正则表达式中)负向查找在哪里。它显示为“一个<,然后是一个单词,然后是不是>的任何内容,最后一个可能不是/,后跟>”。
请注意,这允许类似<a/ >
(与原始正则表达式一样)的东西,因此,如果您想要更严格的限制,则需要构建一个正则表达式以匹配用空格分隔的属性对。
我建议使用QueryPath在PHP中解析XML和HTML。它的语法基本上与jQuery相同,只是在服务器端。
我认为这里的缺点是HTML是Chomsky Type 2语法(无上下文语法),而RegEx是Chomsky Type 3语法(常规语法)。由于类型2语法从根本上比类型3语法复杂(请参阅Chomsky层次结构),因此从数学上讲,无法使用RegEx解析XML。
但是许多人会尝试,有些甚至会声称成功-但直到其他人发现错误并完全把您弄乱为止。
虽然只有正则表达式的任意 HTML是不可能的,但有时使用它们来解析有限的已知 HTML集合是适当的。
如果您想从一小撮HTML页面中抓取数据,然后将它们填充到数据库中,则正则表达式可能会正常工作。例如,我最近想获得我从议会网站上获得的澳大利亚联邦代表的姓名,政党和地区。这是一项有限的一次性工作。
正则表达式对我来说效果很好,并且安装起来非常快。
不要听这些家伙。如果将任务分解成小块,则可以使用regex 完全解析上下文无关的语法。您可以使用按顺序执行每个脚本的脚本来生成正确的模式:
我本人还没有完成最后一部分,但是我知道我已经接近了。CthulhuRlyehWgahnaglFhtagnException
由于某种原因,它总是抛出s,因此我将其移植到VB 6并使用On Error Resume Next
。一旦调查了刚刚在墙上打开的这扇奇怪的门,我将更新代码。嗯
PS Pierre de Fermat也想出了办法,但是他所写的利润不足以编写代码。
尽管为此目的使用正则表达式不适当且无效,但有时正则表达式可以为简单的匹配问题提供快速解决方案,并且在我看来,对于琐碎的工作使用正则表达式并不是那么麻烦。
有一篇关于匹配最里面的HTML元素的权威博客文章,这些元素由Steven Levithan撰写。