我有以下格式的xml文件
<starttag name="AAA" >
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="YYY"/>
</starttag>
<starttag name="BBB" >
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="XXX"/>
</starttag>
<starttag name="CCC" >
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="XXX"/>
<innertag name="XXX" value="YYY"/>
</starttag>
..
..
..
我想提取starttag的所有名称属性,其中任何一个innertag的值都是YYY。
所以在上面的文件中,输出将是AAA和CCC。 我只能使用正则表达式匹配。我想可以使用前瞻但不能为多行创建正则表达式模式。我知道如何使用正则表达式单行,我也尝试使用相同的但没有获得预期的输出。任何人都有进展。
编辑:虽然我已经放了xml示例,但实际上我正在尝试了解多行正则表达式匹配,我正在尝试这个文件,我失败了。请避免使用与XML解析相关的解决方案。
更新:根据史蒂文的建议,继续工作
pcregrep -M '<starttag name="([^"])*"[^>]*>(\s|<innertag[^>]*>)*<innertag name="[^"]*" value="YYY"\/>(\s|<innertag[^>]*>)*<\/starttag>' file.xml
grep -Pzo '<starttag name="([^"])*"[^>]*>(\s|<innertag[^>]*>)*<innertag name="[^"]*" value="YYY"\/>(\s|<innertag[^>]*>)*<\/starttag>' file.xml
答案 0 :(得分:1)
考虑使用XMLStarlet
&#34; XMLStarlet是一组命令行实用程序(工具) 用于转换,查询,验证和编辑XML文档和文件 使用简单的shell命令集以类似的方式为plain执行 使用UNIX grep,sed,awk,diff,patch,join等文本文件 命令&#34;
答案 1 :(得分:0)
XML解析器,尤其是支持XPath的XML解析器将更容易和更稳定,但如果你真的必须坚持使用正则表达式,这里的模式将与你提供的示例输入一起使用:
<starttag name="([^"])*"[^>]*>(\s|<innertag[^>]*>)*<innertag name="[^"]*" value="YYY"\/>(\s|<innertag[^>]*>)*<\/starttag>
它不适用于格式良好的XML文档的所有变体,但只要它们像您的示例一样格式化,您就应该“好”。
默认情况下,正则表达式始终捕获多行。有一个选项,您可以告诉它一次只处理一行,但默认情况下通常不会打开。唯一真正的诀窍是.
模式与换行符不匹配,因此如果要匹配任何字符(包括换行符),则需要使用.|\n
或否定字符诸如[^>]
之类的课程。