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

<p>
<a href="foo">

但不是这些:

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

我想出了这个,想确保我做得对。我只是在捕捉a-z。

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

我相信上面写着:

找到一个小于,然后查找(并捕获)a-z一次或多次,然后找到零个或多个空格,然后查找任何字符零次或多次,贪婪,除了/,然后查找大于

我有这个权利吗?更重要的是,你怎么看?


当前回答

每当我需要从HTML文档中快速提取内容时,我都会使用Tidy将其转换为XML,然后使用XPath或XSLT来获取所需内容。在您的案例中,类似于:

//p/a[@href='foo']

其他回答

OP似乎没有说他需要用标签做什么。例如,他需要提取内部文本,还是只检查标签?

我坚定地认为正则表达式不是万能的文本解析器。我已经编写了大量的文本解析代码,包括用于解析HTML标记的代码。

虽然我确实对正则表达式不太在行,但我认为正则表达式太死板,很难维护这种解析。

如果您只是试图查找这些标记(没有解析的野心),请尝试以下正则表达式:

/<[^/]*?>/g

我在30秒内写下了它,并在这里进行了测试:http://gskinner.com/RegExr/

它匹配您提到的标记类型,而忽略您所说的要忽略的类型。

<\s*(\w+)[^/>]*>

各部分解释如下:

<:起始字符

\s*:标签名称前可能有空格(难看,但可能)。

(\w+):标记可以包含字母和数字(h1)。嗯,w也与“_”匹配,但我想它不会伤害你。如果好奇,请改用([a-zA-Z0-9]+)。

[^/>]*:除了>和/直到关闭>

>:关闭>

不相关的

对于那些低估了正则表达式的人来说,他们说正则表达式的功能和正则语言一样强大:

anbanban不是规则的,甚至不是上下文无关的,可以与^(a+)b\1b\1匹配$

反向引用FTW!

<([a-z][^>\s]*)(?:\s+[^>]+)?>

此正则表达式将匹配由单个单词(例如<p>、<a>等)组成的开头标记,后跟零个或多个空格和任意数量的字符(除了>或空白),然后是结束>字符。它还会将标记与属性匹配,并且不会将标记与包含a-z以外字符的名称匹配。然而,它仍然不会匹配自动关闭标签。

这可能会:

<.*?[^/]>

或不带结束标记:

<[^/].*?[^/]>

HTML解析器上的火焰大战是怎么回事?HTML解析器必须解析(并重建!)整个文档,然后才能对搜索进行分类。在某些情况下,正则表达式可能更快/更优雅。我的2美分。。。