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

<p>
<a href="foo">

但不是这些:

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

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

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

我相信上面写着:

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

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


当前回答

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

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

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

其他回答

无法使用正则表达式解析[X]HTML。因为正则表达式无法解析HTML。Regex不是一个可以用来正确解析HTML的工具。正如我之前多次在这里回答的HTML和正则表达式问题一样,正则表达式的使用不允许您使用HTML。正则表达式是一种不够复杂的工具,无法理解HTML所使用的构造。HTML不是一种正则语言,因此不能由正则表达式解析。Regex查询无法将HTML分解为有意义的部分。很多次,但我都不明白。即使是Perl使用的增强型不规则正则表达式,也无法完成解析HTML的任务。你永远不会让我崩溃。HTML是一种非常复杂的语言,它不能被正则表达式解析。甚至Jon Skeet也无法使用正则表达式解析HTML。每次你试图用正则表达式解析HTML时,这个邪恶的孩子都会痛哭流涕,而俄罗斯黑客则会在你的网络应用程序上进行攻击。用正则表达式解析HTML会将受污染的灵魂召唤到活人的领域。HTML和正则表达式就像爱情、婚姻和仪式性的杀婴。<center>无法保持它太晚了。正则表达式和HTML在同一概念空间中的合力会像水一样摧毁你的思想。如果你用正则表达式解析HTML,你就屈服于他们和他们的亵渎方式,这让我们所有人都要为一个名字无法在基本多语言平面中表达的人付出不人道的努力,他来了。HTML加正则表达式将使n​当你观察时,你的心灵在恐惧的冲击中枯萎。基于x的HTML解析器是杀死StackOverflow的癌症,为时已晚,为时不晚,我们无法得救,因为一个chi͡ld的犯罪确保了regex将吞噬所有的活组织(除了它不能消耗的HTML,如前所预言的那样)亲爱的主,请帮助我们,任何人如何能在这场灾难中幸存下来,使用regex来解析HTML已经注定了人类将遭受永恒的可怕折磨使用正则表达式作为处理HTML的工具的安全漏洞在这个世界和c͒ͪo͛ͫ腐败实体(如SGML实体,但更腐败)的可怕领域之间建立了一个漏洞,这仅仅是对reg世界的一瞥​用于HTML的ex解析器将​他突然把一个程序员的意识带入了一个不断尖叫的世界,瘟疫般的slithy regex感染会​我吞噬你的HT​ML解析器、应用程序和存在一直像Visual Basic一样,但更糟糕的是他来了,他来了就不来了​对他来说​s un̨hoğly radiańcé; destro҉ying all enli̍̈́س\836收紧,HTML标签lea͠ki̧n͘g fr ǫm̡yo​͟我们的眼睛͢s̸̛l̕ik͏e liq​uid pain,re̸gular exp之歌​压缩解析将退出​用英语表达摩尔的声音​来自sp的塔尔曼​在这里我可以看到它,你可以看到它吗​他终于揭穿了谎言​人的全部都是LOS͖̩͇̗̪̏̈́T ALL I​当他来的时候,他就失去了机会​或渗透到我的脸上ᵒ天啊不不不​O NΘ停止​*̶͑̾̾​ͫ͏̙̤g͛838̾ͫ;͇̫̑͆l​ot rȇͧ̌aͨl̘̝̙ͤ͂̾̆ZA̡͊͠LGΌISͮ;҉̛̯͈͕̹ͼ̱TO̶͇̺ͅƝȳ̳TH̘; Ë͖́̉\864 P͍̭O̚​N̐Y̡Hͨ͊̽س̾̎801;̸̪̯E̾;̧̲̬͛ͪ̈́͘809;ͧ⁲̨̦̱̹̭̰C \877̙̝͖̏Oͮ͏7;͍M͊̒ͪ̚873; 876;Ỿ860;̲̖Ȇ∱̛̟͌S̨̥̫͎ͯ̿̔̀ͅ


您是否尝试过改用XML解析器?


主持人说明此帖子已锁定,以防止对其内容进行不当编辑。这篇文章看起来和它应该看起来完全一样——它的内容没有问题。请不要为我们的注意标记。

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

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

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

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

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

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

或者如果没有,就合并。

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

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

如果PHP需要此功能:

除非是正确格式化的XML,否则PHP DOM函数将无法正常工作。不管它们对人类其他人的用处有多大。

simplehtmldom很好,但我发现它有点bug,而且内存很重[会在大页面上崩溃。]

我从未使用过querypath,所以不能评论它的有用性。

另一个可以尝试的是我的DOMParser,它非常节省资源,我已经很高兴地使用了一段时间。简单易学,功能强大。

对于Python和Java,发布了类似的链接。

对于反对者,我只在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;

中国古代军事家、将军和哲学家孙子说过:

据说,如果你了解你的敌人,了解你自己,你可以赢得百战百胜,而不会一败涂地。如果你只了解自己,而不了解对手,你可能会赢,也可能会输。如果你既不了解你自己也不了解你的敌人,你将永远危及自己。

在这种情况下,你的敌人是HTML,你要么是你自己,要么是正则表达式。您甚至可能是带有不规则正则表达式的Perl。了解HTML。了解自己。

我写了一首描述HTML本质的俳句。

HTML has
complexity exceeding
regular language.

我还写了一首俳句,描述Perl中正则表达式的性质。

The regex you seek
is defined within the phrase
<([a-zA-Z]+)(?:[^>]*[^/]*)?>