正则表达式分析/提取XML/XHTML标签属性

本文详细解析了一段用于从HTML中提取标签及其属性的PHP代码,包括标签名、属性及其值的提取过程,并通过示例展示其应用。

直接看代码

<?php #author: selfimpr #blog: http://blog.youkuaiyun.com/lgg201 #mail: lgg860911@yahoo.com.cn $pattern = <<< eot / < #开始标签 (?P<tagname>(?>\w+)) #标签名 (?P<attr> #单个属性子组 (?>\s+) #前置空白 (?P<attr_name>\w+) #属性名 = #赋值符号 (?P<quote>(?P<single_quote>')|(?P<double_quote>")) #读取包裹属性值的引号 (?P<attr_value> #值处理子组 (?: #将值分解处理: 分解为1) 偶数个转义字符的部分; 2) 单个转义字符+引号或非当前使用引号的字符 (?P<slash>(?>(?:\\\\\\\\)*)*) #消耗掉当前位置起偶数个转义字符 (?P<chars> #非转义字符自身的处理 \\\\(?P=quote)|(?(5)[^']|[^"]) #这里用了分支, 一边是转义字符+引号, 另一边是条件匹配的非当前引号字符 ) )* #对值进行的分组进行0次或多次处理 ) (?P=quote) #引号闭合 )* #属性的重复 \s* #后置空白 \/?> #标签闭合处理(这里的焦点在于对属性值的处理, 所以没有对</tagname>的方式进行处理) /x eot; #示例输入 $content1 = <<< eot <a href='\\\\\'aaaa\\\\"\\' alt='中国<a href=\\"www.baidu.com\'\\" >战神啊</a>共和国'> eot; $content2 = <<< eot <a href="\\\\\"aaaa\\\\" alt="中华人民<a href=\\"www.baidu.com\\" >战神啊</a>共和国"> eot; echo $pattern . chr(10); preg_match($pattern, $content1, $matches); print_r($matches); preg_match($pattern, $content2, $matches); print_r($matches);

QString TriopticsParser::preprocessTriopticsForXmlNew(const QString & html) { // 预编译正则表达式(静态变量确保只编译一次) static const QRegularExpression tagRegex( R"(<(\/?)(\w+)([^>]*?)(\/?)>)", QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption ); static const QStringList selfClosingTags = { "img", "br", "meta", "link", "input", "hr", "col", "area", "base", "command", "embed" }; // 预分配结果字符串内存(额外200字符用于XML声明和格式调整) QString result; result.reserve(html.size() + 200); // 查找<html>位置(优化搜索性能) int htmlStart = html.indexOf(QRegularExpression("<html[^>]*>", QRegularExpression::CaseInsensitiveOption)); if (htmlStart == -1) htmlStart = 0; // 添加XML声明(如果尚未添加) if (!result.contains("<?xml")) { result.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); } // 单次遍历处理标签 int pos = htmlStart; const int htmlSize = html.size(); while (pos < htmlSize) { QRegularExpressionMatch match = tagRegex.match(html, pos); if (!match.hasMatch()) { // 添加剩余内容并退出 result.append(html.mid(pos)); break; } // 添加匹配前的内容 if (match.capturedStart() > pos) { result.append(html.mid(pos, match.capturedStart() - pos)); } // 提取标签组件 const QString slash = match.captured(1); // 结束标签的斜杠 QString tagName = match.captured(2).toLower(); // 标签名(小写) const QString attributes = match.captured(3); // 属性字符串 const QString selfClose = match.captured(4); // 自闭合斜杠 // 构建新标签 QString newTag = '<' % slash % tagName; // 添加属性(如果有) if (!attributes.isEmpty()) { newTag += ' ' % attributes.trimmed(); } // 处理自闭合标签 if (selfClosingTags.contains(tagName) || !selfClose.isEmpty()) { // 确保正确自闭合格式 newTag += "/>"; } else { // 常规标签闭合 newTag += '>'; } result.append(newTag); pos = match.capturedEnd(); } // 移除无效闭合标签(优化为单次操作) result.replace(QRegularExpression("</link>", QRegularExpression::CaseInsensitiveOption), ""); // 优化内存使用 result.squeeze(); return result; }为啥调用QDoment的setContent报错
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值