问题描述
假设file.txt
中包含以下内容:
---------
foo bar
more foo bar
---------
当我执行grep -P '(?<=-$)(?s:.)*(?=^-)' file.txt
时,我希望只匹配中间的两行,但是此表达式不匹配。怎么了?
我也尝试过grep -P '(?s)(?<=-$).*(?=^-)' file.txt
,但结果相同。
解决方法
您的模式不起作用,因为
- 仅
P
选项仅使用PCRE正则表达式引擎使grep
匹配 - 由于没有其他选项,
grep
输出完整的匹配行,因此需要添加o
选项以输出匹配的文本,并添加z
以便将文件插入到单个文字 - 您的正则表达式默认具有
^
和$
锚,它们匹配 string 的开始/结束而不是行。您需要一个m
标志和一个s
标志(它使.
匹配包括换行符的任何字符)。
因此,您可以将正则表达式与m
和-oz
一起使用:
grep -Poz '(?ms)(?<=-$).*(?=^-)' file.txt
或者,
grep -Poz '(?s)-\R\K.*(?=\R-)' file.txt
其中\R
插入任何换行序列,而\K
则忽略了与整个内存缓冲区相距甚远的文本。
请参见regex demo。