使用EGREP查找字符串中重复3次或更多次的子字符串

时间:2014-10-14 15:06:20

标签: regex grep

我试图找到任何重复任何4个字子串3次或更多次的字符串,没有重叠(子串不能相互重叠)

这样的事情:

grep -E '([A-Za-z]{4})\1\1' test.txt

我知道这是错的,但我不确定我做错了什么或如何使用字符串重复功能。

我特别感兴趣的是使用EGREP,而不是其他方式。

一些例子:

四个四季都没关系 fourfourfourfour不会好的

没有一个子串可以重叠,所以如果我正在寻找" hehe"在hehehehe,它会返回false,因为只有两个不重叠的匹配。

5 个答案:

答案 0 :(得分:1)

它是一个四字符串然后你可以尝试下面的grep命令。

grep -oP '^(?:(?!\1).)*\K(.{4})(?=(?:(?!\1).)*\1(?:(?!\1).)*\1(?:(?!\1).)*$)' file

答案 1 :(得分:0)

试试这个:

grep -P '^(.*?(....))(?=(.*?\\2){2}(?!(.*\\2){3}).*'

这里的关键是使用不情愿的量词在每个abc之前尽可能少地消耗,然后是负面的预测,以禁止超过3个。

答案 2 :(得分:0)

我必须收回先前的声明。准确得到x个匹配数 似乎在Perl中工作(也可能在PCRE类型中工作)。

这样做是因为在Perl中,变量可以作为多种类型存在,因此每个变量都存在 有一个控制状态。其中一个州是否定义。

因此,捕获缓冲区可以在实际定义之前引用。

This might not apply to command line grep (even in Perl mode), but it might be worth a try.

添加到@ AvinashRaj的正则表达式,可以这样做。我在Perl中测试它,在那里工作:

 # ^(?:(?!\1).)*(.{4})(?:(?!\1).)*\1(?:(?!\1).)*\1(?:(?!\1).)*$

 ^ 
 (?:
      (?! \1 )
      . 
 )*
 ( .{4} )             # (1)
 (?:
      (?! \1 )
      . 
 )*
 \1 
 (?:
      (?! \1 )
      . 
 )*
 \1 
 (?:
      (?! \1 )
      . 
 )*
 $

答案 3 :(得分:0)

由于您要求专门提出grep -E解决方案,而且所有早期的答案似乎都在使用grep -P,这还有一个。

grep -E '(....)\1\1' file

这将寻找一组四个任意字符(包括空格)重复三次,彼此相邻。

如果您想限制为非空格字符,请尝试使用此字符。

grep -E '([^[:space:]]{4})\1\1' file

这看起来更复杂,但实际上并非如此:我们使用[^[:space:]]代替.并指定与{4}重复四次只是因为它真的很难写[^[:space:]][^[:space:]][^[:space:]][^[:space:]]

如果你想放宽邻接要求并在同一输入行上找到一个四字符串,在其间有一些其他字符,那就试试吧。

grep -E '(....).*\1.*\1' file

括号执行分组,但也捕获;无论匹配的第一组括号是否都可用\1。你不能只说(....){3}因为它只是说四个字符,然后是其他四个字符,然后是其他四个字符。

答案 4 :(得分:0)

以下是使用awk的非正则表达式解决方案:

awk '{s=substr($0, 1, 4); print ($0 == s s s)?"match":"no match"}'

<强>测试

echo "fourfourfour" | awk '{s=substr($0, 1, 4); print ($0 == s s s)?"match":"no match"}'
match

echo "hehehehe" | awk '{s=substr($0, 1, 4); print ($0 == s s s)?"match":"no match"}'
no match