You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用grep实现多行且惰性的正则匹配?含XML场景问题

关于grep多行惰性匹配及XML文本处理的解决方案

嗨,针对你提出的两个问题,我来逐一给出实用的解决思路:

1. 能否用grep实现多行且惰性的正则搜索?

完全可以!不过得依赖GNU grep(Linux系统大多默认自带)的参数组合,核心是利用Perl兼容正则(-P)来支持惰性匹配,再配合多行模式参数让grep能跨行匹配:

  • 惰性匹配:Perl正则支持.*?这种非贪婪(惰性)语法,这是扩展正则(-E)不具备的;
  • 多行匹配:可以用-z参数让grep把整个输入文件当作一个连续的文本块(而非逐行处理),再结合Perl正则里的(?s)修饰符,让.能匹配换行符,实现真正的跨行匹配。

2. XML文本中匹配<i>something.*?}</i>的问题解决

你提到-Pzo和-Ezo都无法满足需求,问题根源在这里:

  • -Ezo的问题:扩展正则(-E)本身不支持惰性匹配(.*?是Perl正则专属语法),所以不管怎么搭配参数,都没法实现非贪婪匹配;
  • -Pzo的问题:你可能没在正则里启用单行模式——Perl正则默认.不匹配换行符,哪怕用-z把文件读成一个块,也需要手动加(?s)修饰符让.能匹配任意字符(包括换行)。

具体解决方法:

方法一:修正-Pzo的正则写法

直接在正则开头加上(?s),命令如下:

grep -Pzo '(?s)<i>.*?}</i>' your_xml_file.txt
  • (?s):启用Perl正则的单行模式,让.匹配换行;
  • -z:将整个文件作为单一文本块处理,避免换行截断匹配;
  • -P:启用Perl兼容正则,支持.*?惰性匹配;
  • -o:只输出匹配到的内容,而非整行。
方法二:用Perl命令替代(适配非GNU grep环境)

如果你的系统是macOS这类默认用BSD grep的环境,-P参数可能不可用,直接用Perl命令更靠谱:

perl -0777 -ne 'print "$_\n" while /(?s)<i>.*?}<\/i>/g' your_xml_file.txt
  • -0777:读取整个文件到内存;
  • -ne:循环处理输入,执行指定的正则匹配;
  • /g:全局匹配所有符合条件的内容,逐个输出。
方法三:用专业XML工具(更可靠的长期方案)

正则处理XML其实是“权宜之计”,如果XML结构复杂(比如嵌套标签、属性、不规则换行),正则很容易出错。推荐用专门的XML处理工具,比如xmlstarlet:

# 提取所有包含"}"的<i>标签内容
xmlstarlet sel -t -v '//i[contains(text(), "}")]' your_xml_file.txt

你可以根据实际XML结构调整XPath表达式,这样能更精准、可靠地提取内容。


内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:06:21