pcregrep或grep:使用lookahead搜索不起作用



我正在尝试搜索一个具有前瞻性的regex,它在pcregrep或grep 中不起作用

我想搜索部分的位

  • ,其可以跨越多条线
  • 其在一行的开头以PQXY开始,并且
  • 以线路末端的OFEJ结束,以及
  • 不包含介于之间的PQXY或OFEJ

Generall我在崇高的文本中使用以下内容查找并运行良好

(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJn)

现在我想找到这样的发生次数,所以我尝试使用grep或pcergrep,两者都不起作用。

pcregrep -c "(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJn)" file.txt
zsh: event not found: PQXY|OFEJ).)

和grep

$ grep -c -zoP "(?s)(^PQXY(?:(?!PQXY|OFEJTRANS).)*OFEJTRANSn)" CB_raw_testing_21_feb_CORRECTIONS_0002.txt
zsh: event not found: PQXY|OFEJTRANS).)

我该怎么做这个

基于@paxdiablo和@anubha的回答

主要错误是@paxdiablo 处理的单引号

$ pcregrep -c -M '(^PQXY(?:(?!PQXY|OFEJ).)*OFEJn)' file.txt 
0

正则表达式的解决方案是基于@anubha添加(?s(。当然n也可以代替(R|z)

$ pcregrep -c -M '(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJn)' file.txt
11726

zsh: event not found: PQXY|OFEJ).)

由于这是zsh引发错误,所以它几乎是当然,因为它试图处理双引号中的内容。为了避免这种情况,您应该使用单个引号,例如:

pcregrep -c '(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJn)' file.txt

我没有安装pcregrep,但这里有一份文字记录,显示了echo:的问题

pax> echo "(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJ)"
zsh: event not found: PQXY|OFEJ).)
pax> echo '(?s)(^PQXY(?:(?OFEJ)'
(?s)(^PQXY(?:(?OFEJ)

在解决问题而不是使用特定的工具方面,在这种情况下,我实际上会选择awk(a(。你可以做一些类似的事情:

awk '/^PQXY/     { s = $0; c = 1; next}
/OFEJ$/     { if (c == 1) { print s""ORS""$0; c = 0 }; next }
/OFEJ|PQXY/ { c = 0; next }
c == 1      { s = s""ORS""$0 }' inputFile

这是通过使用字符串和标志来控制收集的行和状态来实现的,最初它们是空字符串和零。

然后,对于每一行:

  • 如果它以PQXY开始,则存储该行并设置采集标志,然后转到下一个输入行
  • 否则,若它以OFEJ结束并且您正在收集,则输出收集的部分并停止收集,然后转到下一个输入行
  • 否则,若其中包含任意一个字符串,则停止收集,移动到下一个输入行
  • 否则,若正在收集,请附加当前行并(隐式(移动到下一个输入行

我已经用一些有限的测试数据进行了测试,它似乎可以正常工作。这是我用于测试的bash脚本(b(,您可以根据需要添加任意多的测试用例,这样可以解决您的问题。

for i in 
"PQXY 1nabcn2 OFEJn" 
"PQXY 1nabcn2 OFEJxn" 
"PQXY 1nabcn  PQXY n2 OFEJn" 
"PQXY 1nabcn  OFEJ n2 OFEJn" 
"PQXY 1nabcndefnPQXY 2n2 OFEJn" 
; do
echo "$i:"
printf "$i" | awk '
/^PQXY/     { s = $0; c = 1; next}
/OFEJ$/     { if (c == 1) { print s""ORS""$0; c = 0 }; next }
/OFEJ|PQXY/ { c = 0; next }
c == 1      { s = s""ORS""$0 }' | sed 's/^/    /
'
done

这是输出,所以你可以看到它的作用:

PQXY 1nabcn2 OFEJn:
PQXY 1
abc
2 OFEJ
PQXY 1nabcn2 OFEJxn:
PQXY 1nabcn  PQXY n2 OFEJn:
PQXY 1nabcn  OFEJ n2 OFEJn:
PQXY 1nabcndefnPQXY 2n2 OFEJn:
PQXY 2
2 OFEJ

(a(根据我的经验,如果你用grep风格的正则表达式尝试了三件事都没有成功,那么转移到更高级的工具通常会更快:-(


(b(是的,我知道它是用bash而不是zsh写的,但这是因为:

  • 这是一个测试程序,向您展示awk的工作原理,因此使用的语言无关紧要;以及
  • 我对bashzsh:-舒服得多。(

使用gnu grep:

grep -ozP '(?ms)^PQXY(?:(?!PQXY|OFEJ).)*OFEJ(R|z)' file
  • 必须使用-z选项将输入和输出数据视为行序列,每个行以零字节结束。

  • 请确保对您的模式使用单引号,这样shell的历史记录模块就不会试图处理!

  • 添加了(?m)(MULTILINE(修饰符,允许在正则表达式中为每行使用^$
  • 使用(R|z)允许结束模式在文件末尾不带换行符的情况下结束。R匹配换行符的任何ind,包括unicode字符,z匹配输入的末尾

工作演示


pcregrep中的等效解

pcregrep -M '(?s)^PQXY(?:(?!PQXY|OFEJ).)*OFEJ(R|z)' file

CCD_ 26启用CCD_ 27中的多行光学。

相关内容

  • 没有找到相关文章

最新更新