在 bash 脚本中根据模式提取字符串

在 bash 脚本中根据模式提取字符串

在 bash 中,假设我有一个字符串strname

strname="ph7go04325r"

我想提取第一的 "3"性格和最后的 "r"中的字符strname,将结果保存在字符串中strresult。在上面的示例中,结果strresult将是:

strresult="25"

第一个"3"字符是不是必须位于 中的字符串位置 8 strname;同样,最后一个"r"不是必然位于字符串位置 11。因此,以下两个字符串都strname应该产生strresult="25"

strname="ph11go04325raa"
strname="325r"
strname="rgo04325raa"

另外,strname=ph12go04330raa"应该产生strresult="30".

我是 bash 脚本新手,我不知道从哪里开始进行这样的字符串模式匹配。你有什么建议吗?

答案1

您可以在 bash(3.0 或更高版本)中使用正则表达式来完成此操作:

if [[ $strname =~ 3(.+)r ]]; then
    strresult=${BASH_REMATCH[1]}
else
    echo "unable to parse string $strname"
fi

在 bash 中,来自正则表达式的捕获组被放置在特殊的 array 中BASH_REMATCH。元素 0 包含整个匹配项,元素 1 包含第一个捕获组的匹配项。

答案2

在标准sh语法中(因此可以与任何版本bash或任何其他兼容 POSIX 的 shell 一起使用),您可以执行以下操作:

case $strname in
  (*3*r*) 
    strresult=${strname#*3}
    strresult=${strresult%r*};;
  (*)
    printf >&2 '%s\n' "Unable to parse string $strname"
esac

另请参阅旧的expr解决方案,它甚至可以在 35 年历史的 Unices 上运行:

expr "x$strname" : 'x[^3]*3\(.*\)r'

老人怪癖with 的意思是,如果匹配失败,您将获得非零退出状态(很好),但如果返回的字符串解析为 0(如 with ),expr您也会获得非零退出状态。strname=zz300rzz

相关内容