【问题标题】:regex issue Bash正则表达式问题 Bash
【发布时间】:2015-12-30 18:43:02
【问题描述】:

我正在学习 bash 编程,特别是正则表达式,我发现了这段代码:

numpat='^[+-]([0-9]+)$'
strpat='^([a-z]*)\1$'

read stringa

if [[ $stringa =~ $numpat ]]
then
    echo "numero"
    echo numero > output
    exit ${BASH_REMATCH[1]}
elif [[ $stringa =~ $strpat ]]
then
    echo "echo"
    echo echo > output
    exit 11
fi

我不明白这一行中的\1 是什么意思:

strpat='^([a-z]*)\1$'

【问题讨论】:

  • 你读过正则表达式教程吗?他们应该解释表达的每个元素的含义。

标签: regex linux bash


【解决方案1】:

\1 是一个backreference。它匹配第一个捕获组 ([a-z]*) 匹配的任何内容。

因此,模式^([a-z]*)\1$ 匹配由重复两次的子字符串构建的字符串,例如foofoo。捕获组匹配第一个foo,反向引用匹配第二个foo。但如果字符串是foobar,则反向引用永远不会匹配任何内容,因为它找不到任何初始字符串的另一个重复。

您可以通过在\1 之后使用+ 量词来允许任意数量的重复。这匹配它一次或多次。

DEMO

【讨论】:

  • 我也这么认为。但是,将 * 作为模式使其变得贪婪,因此它可能不会匹配其他任何东西。如果我测试它,它不起作用:[[ "foofoo" =~ ^([a-z]*)\1$ ]] && echo "yes" || echo "no" 返回no
  • 虽然我可以重现这种行为,但根据定义,扩展的 posix 正则表达式支持反向引用。
  • 区别似乎在于模式是在变量中还是在文字中。
  • @ginogino 你也可以^([a-z]*)\1{4}$
  • @Barmar:“区别似乎在于模式是在变量中还是在文字中”——不在我的机器上。它只匹配1
【解决方案2】:

在使用 newlibcygwin 上,\1 仅匹配 1

if [[ a1 =~ $strpat ]]; then echo YES; fi   # YES

【讨论】:

  • 不在 my bash 中。在 my bash 中,它的工作方式类似于反向引用,这意味着它匹配 foofoo 但不匹配 foobar。这很奇怪!我有GNU bash, version 4.3.42(1)-release
  • 认真的吗? bash 4.1.10(4)-在 cygwin 上发布。
  • @hek2mgl Bash 在man 3 regex 中使用 ERE,虽然在某些实现中可能支持反向引用,但 ERE 标准中没有反向引用。
  • 不幸的是,有很多正则表达式变体......这并不奇怪,grep 反向引用在我的机器上工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
  • 2011-01-25
相关资源
最近更新 更多