正则表达式问题:在随机位置上仅匹配序列n次

时间:2011-01-07 21:47:47

标签: regex grep

我有一个正则表达式问题,例如:

  1. ... AAA的 BZBZB CCCDDD ...
  2. ... BZBZB DDD BZBZB CCC ...
  3. 我正在寻找一个与 BZBZB 匹配的正则表达式 n 次。
    在一行中。所以,如果我只想将序列匹配一次,我应该只将第一行作为输出。

    该字符串出现在文本中的随机位置。正则表达式应该与grep或egrep兼容...

    提前谢谢。

3 个答案:

答案 0 :(得分:9)

grep '\(.*BZBZB\)\{5\}'将执行5次,但这将匹配任何出现5次或更多次的内容,因为grep会检查行的任何子字符串是否匹配。因为grep没有任何方法可以对正则表达式中的字符串进行负匹配(只有字符),所以单个命令无法做到这一点,除非,例如,您知道要匹配的字符串中使用的字符不是在其他地方使用过。

但是,您可以使用两个grep命令执行此操作:

cat temp.txt | grep '\(.*BZBZB\)\{5\}' | grep -v '\(.*BZBZB\)\{6\}'

将返回BZBZB恰好出现5次的行。 (基本上,它会进行5次或更多次的正面检查,然后进行6次或更多次的否定检查。)

答案 1 :(得分:1)

从grep手册页:

   -m NUM, --max-count=NUM
    Stop  reading  a file after NUM matching lines.  If the input is
    standard input from a regular file, and NUM matching  lines  are
    output,  grep  ensures  that the standard input is positioned to
    just after the last matching line before exiting, regardless  of
    the  presence of trailing context lines.  This enables a calling
    process to resume a search.  When grep stops after NUM  matching
    lines,  it  outputs  any trailing context lines.  When the -c or
    --count option is also  used,  grep  does  not  output  a  count
    greater  than NUM.  When the -v or --invert-match option is also
    used, grep stops after outputting NUM non-matching lines.

所以我们需要两个grep表达式:

grep -e "BZ" -o
grep -e "BZ" -m n

第一个在前一个字符串中查找“BZ”的所有实例,但不包括行周围的内容。每个实例都在自己的行中吐出。第二行将每条线吐出并继续直到找到n条线。

>>>"ABZABZABX" |grep -e "BZ" -o | grep -e "BZ" -m 1
BZ

希望这就是你所需要的。

答案 2 :(得分:0)

它的丑陋但如果grep可以向前看断言,这应该有效:

/^(((?!BZBZB).)*BZBZB){5}((?!BZBZB).)*$/

编辑 - 上面的{5}是OP中的n倍变量。        看起来像GNU grep使用-P选项做Perl之类的断言。

Perl样本

use strict;  
use warnings;  

my @strary = (  
  'this is BZBZB BZBZB BZBZB and 4 BZBZB then 5 BZBZB and done',  
  'BZBZBBZBZBBZBZBBZBZBBZBZBBZBZBBZBZBBZBZB BZBZB  BZBZB',  
  'BZBZBBZBZBBZBZBBZBZBBZBZB 1',  
  'BZBZBZBBZBZBBZBZBBZBZBBZBZBBZBZB 2',  
);  

my @result = grep /^(((?!BZBZB).)*BZBZB){5}((?!BZBZB).)*$/,  @strary;  

for (@result) {  
   print "Found: '$_'\n";  
}  

输出

Found: 'this is BZBZB BZBZB BZBZB and 4 BZBZB then 5 BZBZB and done'
Found: 'BZBZBBZBZBBZBZBBZBZBBZBZB 1'