以任何顺序匹配多个模式(Perl)

时间:2014-11-12 16:59:11

标签: regex perl

我有一个看起来像(但更大)的文件:

arbstring1014: 120|PROKKA_00511 630|PROKKA_01218 630|PROKKA_01999 630|PROKKA_00506
arbstring1015: 120|PROKKA_02025 630|PROKKA_03113 120|PROKKA_02363 196|PROKKA_02308
arbstring1016: 120|PROKKA_02059 196|PROKKA_03630 630|PROKKA_03589 630|PROKKA_00462
arbstring1017: 120|PROKKA_02961 196|PROKKA_03061 630|PROKKA_03283 120|PROKKA_03099
arbstring1025: 120|PROKKA_02979 196|PROKKA_02928 630|PROKKA_03158
arbstring1026: 120|PROKKA_00924 196|PROKKA_00857 630|PROKKA_00906
arbstring1027: 120|PROKKA_02739 196|PROKKA_02684 630|PROKKA_02848
arbstring1028: 120|PROKKA_01415 196|PROKKA_01350 630|PROKKA_01503
arbstring1029: 120|PROKKA_03195 196|PROKKA_03175 630|PROKKA_03374
arbstring1030: 120|PROKKA_03050 196|PROKKA_03001 630|PROKKA_03230

我想在“PROKKA_XXXXX”之前找到包含所有这些行的行:

120|
196|
630|

下面的脚本会找到它们,但看起来只是按照它们在脚本中写入的顺序(例如,只返回一行196 |,120 |,630 |当我知道有一些事实全部三个,但顺序不同):

#!/usr/bin/perl -w use strict; use warnings;

#get genes that are present in all groups  from a groups.txt

#scans through output of orthomcl to get genes that are only core open (IN,"<$ARGV[0]")  or die $!;

while (my $line = <IN>) {
#change the VS1 to match your unique phage ID add "& ($line =~m/VS11\|/)" to add more rules to match . will need 15 for 15 phage if ($line =~ m/196\|/gi && $line =~ m/120\|/gi && $line =~
m/630\|/gi)#(=~m/120\|/gi))#($line =~m/196\|/gi)

#if (/(?=.*re1)(?=.*re2)(?=.*re3)/s)

#& ($line =~m/630\|/) & ($line =~m/120\|/)   #& ($line =~m/IME1\|/) #&
#($line =~m/KBNP\|/) & ($line =~m/LUZ7\|/) & ($line =~m/PA26\|/) & ($line =~m/RLP1\|/) & ($line =~m/VC01\|/) &
#($line =~m/DSS3\|/)  & ($line =~m/EcP1\|/)  & ($line =~m/G7C\|/) & ($line =~m/JA1\|/) & ($line =~m/LIT1\|/) &
#($line =~m/N4\|/) & ($line =~m/pS6\|/) & ($line =~m/RPP1\|/) & ($line =~m/VBP3\|/) & ($line =~m/VBP4\|/) &
#($line =~m/058\|/)  &  ($line =~m/076\|/)  &  ($line =~m/JWA\|/)  &  ($line =~m/JWD\|/) & ($line =~m/PRES\|/)    { print $line ; } }

任何有关这方面的帮助都会很棒,因为我已经看了一下......

2 个答案:

答案 0 :(得分:2)

我建议使用预测:

^
(?=.*120\|PROKKA_\d+)
(?=.*196\|PROKKA_\d+)
(?=.*630\|PROKKA_\d+)
.*

regex101.com demo

(为了便于阅读,这在多行中分开)。从每行的开头开始,预览所有3个条件:120,196和630.如果找到它们,.*将匹配该行。

答案 1 :(得分:0)

你在那里粘贴的代码有答案,甚至在评论中解释它,除了它搞砸了。

你粘贴的内容:

while (my $line = <IN>) {
#change the VS1 to match your unique phage ID add "& ($line =~m/VS11\|/)" to add more rules to match . will need 15 for 15 phage if ($line =~ m/196\|/gi && $line =~ m/120\|/gi && $line =~
m/630\|/gi)#(=~m/120\|/gi))#($line =~m/196\|/gi)

没有任何意义。似乎是有意的:

while (my $line = <IN>) {
# change the numbers, which are phage IDs;
# e.g., to match your unique phage ID, say 196, add:
#   && ($line =~ m/196\|/)
#
  if ($line =~ m/196\|/gi && $line =~ m/120\|/gi && $line =~ m/630\|/gi)) {

然后在$line匹配这三个的情况下执行代码,在代码之后, 必须关闭ifwhile条款:

  }
}

这可以更具可读性,但我们需要完整的脚本。