我有一个正则表达式问题,例如:
我正在寻找一个与 BZBZB 匹配的正则表达式 n 次。
在一行中。所以,如果我只想将序列匹配一次,我应该只将第一行作为输出。
该字符串出现在文本中的随机位置。正则表达式应该与grep或egrep兼容...
提前谢谢。
答案 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'