我需要匹配XML属性中出现的所有"标签"(例如%thisIsATag%)。 (注意:我保证会收到有效的XML,因此无需使用完整的DOM遍历)。 我的正则表达式正在工作,除了在单个属性中有两个标签时,仅返回最后一个。
换句话说,此正则表达式应找到tag1,tag2,...,tag6。 但是,它省略了tag2和tag5。
这是一个有趣的小测试工具(PHP):
$xml = <<
XML;
$matches = null;
preg_match_all('#]+("([^%>"]*%([^%>"]+)%[^%>"]*)+"|\'([^%>\']*%([^%>\']+)%[^%>\']*)+\')[^>]*>#i', $xml, $matches);
print_r($matches);
?>
谢谢!:)
您要尝试的是从每次正则表达式匹配不止一次的组中恢复中间捕获。 据我所知,只有.NET和Perl 6提供了该功能。 您必须分两个阶段完成工作:将属性值与其中的一个或多个%tag%序列匹配,然后分解各个序列。
您似乎并不在乎这些值与哪个XML标记或属性相关联,因此您可以使用这种稍微简单的正则表达式来查找其中带有%tag%序列的值:
'#"([^"%<>]*+%[^%"]++%[^"]*+)"|\'([^\'%<>]*+%[^%\']++%[^\']*+)\'#'
编辑:该正则表达式捕获组1或组2中的属性值,具体取决于它使用的引号。 这是合并替代方案的另一个版本,因此它始终可以将值保存在组2中:
'#(["\'])((?:(?![%<>]|\1).)*+%(?:(?!%|\1).)++%(?:(?!\1).)*+)\1#'
虽然其他解决方案要简单得多,但仍然可以解决相同的基本问题,但是这个解决了我的问题的奥秘。关键要点是,在PHP(和大多数语言)中,我无法"恢复中间捕获"。我想这很有道理!很高兴知道。 :)
其他答案还假定%tag%名称只能由字母数字或"单词"字符组成,并且%ThingsThatLookLikeTags%实际上总是标记,无论它们出现在什么地方。我的仅将它们与带引号的字符串匹配-假定它们将始终是属性值。但是我可以扩展它以匹配仅在(XML)标记内的字符串。
% w +%将是一种更简单的方法。
+1可进一步简化操作。
Mentee是最终的regex专家
这是:
(%[a-zA-Z0-9]+%)
不够? 在您的示例中,标记不会出现在属性值之外的任何地方-可以吗?
+1哈哈!有趣的是,有时我们会忽略最简单的解决方案... :)我想这在大多数情况下都是可行的。使我感到不安的唯一一件事是XML确实变得更加复杂,并且类似标签的文本也可能出现在元素的主体中……但是,再次,这可能是目前足够的解决方案。谢谢 !:)