如何在bash中使用正则表达式operator =〜匹配重复的字符?

时间:2017-09-12 14:52:29

标签: regex bash

我想知道字符串是否重复6次或更多次字母,使用=〜运算符。

a="aaaaaaazxc2"
if [[ $a =~ ([a-z])\1{5,} ]];
then
     echo "repeated characters"
fi

上面的代码不起作用。

3 个答案:

答案 0 :(得分:3)

BASH正则表达式风格,即 ERE 不支持正则表达式中的反向引用。 ksh93 and zsh support it though

作为替代解决方案,您可以使用grep中的扩展正则表达式选项来执行此操作:

a="aaaaaaazxc2"
grep -qE '([a-zA-Z])\1{5}' <<< "$a" && echo "repeated characters"

repeated characters

编辑:某些ERE实施支持反向引用作为扩展。例如Ubuntu 14.04支持它。请参阅以下代码段:

$> echo $BASH_VERSION
4.3.11(1)-release

$> a="aaaaaaazxc2"
$> re='([a-z])\1{5}'
$> [[ $a =~ $re ]] && echo "repeated characters"
repeated characters

答案 1 :(得分:2)

[[ $var =~ $regex ]]解析POSIX ERE语法中的正则表达式。

请参阅the POSIX regex standard,重点补充:

  

BACKREF - 仅适用于基本正则表达式。字符串由一个字符后跟一位数字,'1'到'9'组成。

针对ERE的POSIX标准未正式指定反向引用;因此,它们不能保证在bash的本地正则表达式语法中可用(受特定于平台的libc扩展),因此强制使用外部工具(awk,grep等)。

答案 2 :(得分:1)

对于一个字符重复的特定情况,您不需要反向引用的全部功能。您可以构建正则表达式,以检查每个小写字母的重复次数

regex="a{6}"
for x in {b..z} ; do regex="$regex|$x{6}" ; done    
if [[ "$a" =~ ($regex) ]] ; then echo "repeated characters" ; fi

使用上面的for循环构建的正则表达式看起来像

> echo "$regex" | fold -w60
a{6}|b{6}|c{6}|d{6}|e{6}|f{6}|g{6}|h{6}|i{6}|j{6}|k{6}|l{6}|
m{6}|n{6}|o{6}|p{6}|q{6}|r{6}|s{6}|t{6}|u{6}|v{6}|w{6}|x{6}|
y{6}|z{6}

此正则表达式的行为与您期望的一样

> if [[ "abcdefghijkl" =~ ($regex) ]] ; then \
  echo "repeated characters" ; else echo "no repeat detected" ; fi
no repeat detected
> if [[ "aabbbbbbbbbcc" =~ ($regex) ]] ; then \
  echo "repeated characters" ; else echo "no repeat detected" ; fi
repeated characters
来自@sln的评论

更新了,用简单的{6,}替换了绑定的{6}表达式。