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

<p>
<a href="foo">

但不是这些:

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

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

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

我相信上面写着:

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

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


当前回答

如果您只需要标记名,那么应该可以通过正则表达式执行此操作。

<([a-zA-Z]+)(?:[^>]*[^/] *)?>

应该做你需要的事。但我认为“莫里茨”的解决方案已经很好了。我一开始没看到。

对于所有反对者:在某些情况下,使用正则表达式是有意义的,因为这可能是最简单、最快捷的解决方案。我同意一般情况下不应该用正则表达式解析HTML。

但是当你有一个HTML子集,你知道格式并且你只想提取一些值时,正则表达式可以是一个非常强大的工具。我这样做了数百次,几乎总是达到我想要的目的。

其他回答

免责声明:如果您有选择,请使用解析器。那是说。。。

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

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

它可能并不完美,但我通过大量HTML运行了这段代码。注意,它甚至会捕捉到一些奇怪的东西,比如出现在网络上的<a name=“badgenerator”“>。

我想,为了使其不匹配自包含的标签,您可能需要使用Kobi的负面外观:

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

或者如果没有,就合并。

对于下选民:这是从实际产品中工作的代码。我怀疑任何阅读此页面的人都会觉得在HTML上使用正则表达式是社会可以接受的。

注意:我应该注意,这个正则表达式在CDATA块、注释以及脚本和样式元素的存在下仍然会崩溃。好消息是,你可以去掉那些使用正则表达式的。。。

虽然只有正则表达式的任意HTML是不可能的,但有时使用它们来解析一组有限的已知HTML是合适的。

如果您有一小组HTML页面,希望从中提取数据,然后将其填充到数据库中,正则表达式可能会很好地工作。例如,我最近想获得澳大利亚联邦代表的姓名、党派和选区,这是我从议会网站上得到的。这是一份有限的一次性工作。

Regexes对我来说很好,而且安装速度很快。

我想这可能有用

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

这可以在这里进行测试。


根据W3学校。。。

XML命名规则

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

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


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

这里有一些很好的正则表达式,可以用BBCode替换HTML。对于所有反对者来说,请注意,他并不是试图完全解析HTML,只是为了净化它。他可能可以消除那些简单的“解析器”无法理解的标记。

例如:

$store =~ s/http:/http:\/\//gi;
$store =~ s/https:/https:\/\//gi;
$baseurl = $store;

if (!$query->param("ascii")) {
    $html =~ s/\s\s+/\n/gi;
    $html =~ s/<pre(.*?)>(.*?)<\/pre>/\[code]$2\[\/code]/sgmi;
}

$html =~ s/\n//gi;
$html =~ s/\r\r//gi;
$html =~ s/$baseurl//gi;
$html =~ s/<h[1-7](.*?)>(.*?)<\/h[1-7]>/\n\[b]$2\[\/b]\n/sgmi;
$html =~ s/<p>/\n\n/gi;
$html =~ s/<br(.*?)>/\n/gi;
$html =~ s/<textarea(.*?)>(.*?)<\/textarea>/\[code]$2\[\/code]/sgmi;
$html =~ s/<b>(.*?)<\/b>/\[b]$1\[\/b]/gi;
$html =~ s/<i>(.*?)<\/i>/\[i]$1\[\/i]/gi;
$html =~ s/<u>(.*?)<\/u>/\[u]$1\[\/u]/gi;
$html =~ s/<em>(.*?)<\/em>/\[i]$1\[\/i]/gi;
$html =~ s/<strong>(.*?)<\/strong>/\[b]$1\[\/b]/gi;
$html =~ s/<cite>(.*?)<\/cite>/\[i]$1\[\/i]/gi;
$html =~ s/<font color="(.*?)">(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi;
$html =~ s/<font color=(.*?)>(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi;
$html =~ s/<link(.*?)>//gi;
$html =~ s/<li(.*?)>(.*?)<\/li>/\[\*]$2/gi;
$html =~ s/<ul(.*?)>/\[list]/gi;
$html =~ s/<\/ul>/\[\/list]/gi;
$html =~ s/<div>/\n/gi;
$html =~ s/<\/div>/\n/gi;
$html =~ s/<td(.*?)>/ /gi;
$html =~ s/<tr(.*?)>/\n/gi;

$html =~ s/<img(.*?)src="(.*?)"(.*?)>/\[img]$baseurl\/$2\[\/img]/gi;
$html =~ s/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/\[url=$baseurl\/$2]$4\[\/url]/gi;
$html =~ s/\[url=$baseurl\/http:\/\/(.*?)](.*?)\[\/url]/\[url=http:\/\/$1]$2\[\/url]/gi;
$html =~ s/\[img]$baseurl\/http:\/\/(.*?)\[\/img]/\[img]http:\/\/$1\[\/img]/gi;

$html =~ s/<head>(.*?)<\/head>//sgmi;
$html =~ s/<object>(.*?)<\/object>//sgmi;
$html =~ s/<script(.*?)>(.*?)<\/script>//sgmi;
$html =~ s/<style(.*?)>(.*?)<\/style>//sgmi;
$html =~ s/<title>(.*?)<\/title>//sgmi;
$html =~ s/<!--(.*?)-->/\n/sgmi;

$html =~ s/\/\//\//gi;
$html =~ s/http:\//http:\/\//gi;
$html =~ s/https:\//https:\/\//gi;

$html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsi;
$html =~ s/\r\r//gi;
$html =~ s/\[img]\//\[img]/gi;
$html =~ s/\[url=\//\[url=/gi;

我建议在PHP中使用QueryPath解析XML和HTML。它的语法与jQuery基本相同,只是在服务器端。