匹配 case 语句内的有效版本号

匹配 case 语句内的有效版本号

我想匹配case语句中的版本号。版本号可能如下所示

1.12.0.32
1.12.0.32.1
2.10.0.30.1.2

并存储在 shell 变量中:version.

正如我在互联网上搜索的那样,在 - 语句中匹配正则表达式并不困难case。但是,有没有人有想法或可以帮助如何在 - 语句中完成它case

我尝试了以下方法,但没有成功:

case "$version" in
    "([0-9]+\.*)+")
                  echo "Correct"
        ;;
                 *)
                  echo "Not Correct"
        ;;
esac

答案1

case仅支持 shell 模式,不支持正则表达式。但 Bash 支持使用不同语法的开箱即用的正则表达式。

如果您的意思是“由点分隔的任意数量的十进制数字”,并且例如没有尾随字母或标签,那么该模式^[0-9]+(\.[0-9]+)*$可能是合适的。([0-9]+\.*)+还可以匹配带有连续点或尾随点的字符串,例如1.2..3..所以:

#!/bin/bash
re='^[0-9]+(\.[0-9]+)*$';
if [[ $version =~ $re ]]; then
    echo "'$version' matches the pattern"
else
    echo "'$version' doesn't match"
fi

正则表达式表示查找任意数量的十进制数字 ( [0-9]+),后跟(·)*由文字点 ( \.) 和任意数量的十进制数字( ) 组成的任意数量的组 ( [0-9]+)。^并将$模式锁定到字符串的开头和结尾,否则匹配的子字符串就足以进行匹配。

这将允许版本字符串没有任何点,例如123.如果您想要至少需要两个数字和点,请使用^[0-9]+(\.[0-9]+)+$(将最后一个更改*+)。

请注意,根据区域设置,[0-9]匹配的内容可能会有点令人惊讶,它可能包含一些更奇怪的 Unicode 数字。用 拼写出允许的字符[0123456789]会更严格,但写起来更尴尬且容易出错。

答案2

case匹配 shell 模式,而不是正则表达式。因此,^[0-9]+(\.[0-9]+)*$您可以使用以下命令来代替正则表达式:

case $version in
  '' | *[!0123456789.]* | .* | *. | *..* ) echo invalid;;
  * ) echo fine;;
esac

即“反转”匹配意义,使用标准 shell 模式来检测无效情况。

请注意,extglobbash 选项适用于case语句中的匹配。因此,如果您使用 进行了设置shopt -s extglob,那么那些扩展模式(如+()*()等)将获得其特殊含义,并且您可以通过使用(shell 模式已经“锚定”到开头和结尾)进行更像正则表达式的正匹配+([0123456789])*(.+([0123456789]))

答案3

如果不是必须的,case并且您允许使用像 之类的外部工具grep,则可以使用if可能提供更大灵活性的语句:

if grep -q -E '^[0-9]+(\.[0-9]+)*$' <<< "$version"
then
    printf "%s is a valid version\n" "$version"
else
    printf "%s is NOT a valid version\n" "$version"
fi

这将接受包含以下内容的版本字符串

  • 至少一个字段由一位或多位连续数字 ( [0-9]+) 组成,后跟
  • 零个或多个以分隔符.(转义为\.正则表达式中的简单意思.是“任何字符”),后跟一个或多个连续数字(再次[0-9]+)。

^通过将匹配锚定到字符串的开始 ( ) 和结束 ( )来确保匹配的详尽性$,因此单纯的子字符串匹配不会触发结果。

相关内容