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

<p>
<a href="foo">

但不是这些:

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

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

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

我相信上面写着:

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

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


当前回答

我想这可能有用

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

这可以在这里进行测试。


根据W3学校。。。

XML命名规则

XML元素必须遵循以下命名规则:

名称可以包含字母、数字和其他字符名称不能以数字或标点字符开头名称不能以字母xml(或xml、xml等)开头名称不能包含空格可以使用任何名称,不保留任何单词。


我使用的模式将遵循这些规则。

其他回答

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

/<[^/]*?>/g

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

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

虽然不能用正则表达式解析HTML的答案是正确的,但它们在这里并不适用。OP只想用正则表达式解析一个HTML标记,这可以用正则表达式完成。

不过,建议的正则表达式是错误的:

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

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

我的建议是

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

其中(?<!…)是(在Perl正则表达式中)后面的否定外观。它的意思是“a<,然后是一个单词,然后是任何不是a>的东西,最后一个可能不是a/,后面是>”。

请注意,这允许使用<a/>(就像原始的正则表达式一样),因此如果您需要更严格的限制,则需要构建正则表达式以匹配由空格分隔的属性对。

您希望第一个>前面不带/。请查看此处了解如何执行此操作的详细信息。这被称为消极的后顾。

然而,在这个示例文档中,这一天真的实现最终将与<bar/></foo>匹配

<foo><bar/></foo>

你能提供更多关于你试图解决的问题的信息吗?您是否以编程方式遍历标签?

我以前使用过一个名为HTMLParser的开源工具。它被设计为以各种方式解析HTML,并且很好地达到了目的。它可以将HTML解析为不同的树节点,您可以轻松地使用它的API从节点中获取属性。看看它,看看这对你有没有帮助。

Try:

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

它与您的类似,但最后一个>不能在斜杠之后,也接受h1。