我需要一个正则表达式,它是匹配的内容的<cherry>
标签,这不是另一个标签的一部分。不满意,我不能使用PHP DOM解析器,因为标记的内容有时包含非常特殊的字符。
以下是传入输入的示例:
<cherry>test</cherry>
<banana>
<cherry>test</cherry>
some text
</banana>
这是我当前的正则表达式,但它也将与<banana>
标记中的<cherry>
标记相匹配
(<cherry>)(.*?)(<\/cherry>)
如何排除其他标签中的匹配项?
我已经试过很多次了。
发布于 2017-09-06 16:00:49
为什么不使用DOMDocument
类而不是正则表达式。只需加载DOM,然后使用getElementsByTagName
获取标记即可。这样,您可以排除任何其他您不想要的标签,而只获得您想要的标签。
示例
<?php
$xml = <<< XML
<?xml version="1.0" encoding="utf-8"?>
<books>
<book>Patterns of Enterprise Application Architecture</book>
<book>Design Patterns: Elements of Reusable Software Design</book>
<book>Clean Code</book>
</books>
XML;
$dom = new DOMDocument;
$dom->loadXML($xml);
$books = $dom->getElementsByTagName('book');
foreach ($books as $book) {
echo $book->nodeValue, PHP_EOL;
}
?>
阅读材料
DOMDocument
发布于 2017-09-06 17:11:53
假设您只需要顶层的数学标记的内容,而不需要其他任何内容,而且到目前为止还不能做到这一点,因为数学标记包含无效的xml,因此任何xml解析器都放弃了...(如问题和评论中所述)
干净的方法可能是,使用某种容错xml解析器(或容错模式)或整理之前的输入。然而,这些方法都可能“破坏”内容。
老生常谈且可能很脏的方法如下,这很可能有其他问题,如果剩余的xml也是无效的,或者您的数学标记是嵌套的,则尤其是(这将导致xml解析器在步骤2中失败):
<math>.*</math>
(不贪婪)(最好是一些独特的uniqid
可能会有所帮助,但一个简单的计数器可能就足够了)通过preg_replace_callback
或使用通用xml解析器对文档进行解析(将其包装在某个根标记中,作为根节点的所有子节点/所有根节点,查看在步骤1中生成了哪些节点。例如:
<math>some invalid xml</math>
<sometag>
<math>more invalid xml</math>
some text
</sometag>
替换为
$replacements = [];
$newcontent = preg_replace_callback(
'/'.preg_quote('<math>','/').'(.*)'.preg_quote('</math>','/').'/siU',
function($hit) use ($replacements) {
$id = uniqid();
$replacements[$id] = $hit[1];
return '<math id="'.$id.'" />';
},
$originalcontent);
这将把你的内容变成:
<math id="1stuniqid" />
<sometag>
<math id="2nduniqid" />
some text
</sometag>
现在使用您选择的xml解析器,选择所有根级别/基本级别元素并查找/math/@id
(我的XPath可能就是错误的,请根据需要进行调整)。结果应该包含所有uniqid,您可以在替换数组中查找
编辑:修复了一些preg_quote
问题,并使用了更多的标准分隔符。
https://stackoverflow.com/questions/46069699
复制相似问题