Bash正则表达式:匹配数字0-1000

时间:2016-05-15 04:48:57

标签: regex bash scripting glob

我正在编写一个脚本,该脚本根据包含脚本文件名的数组执行存储在给定目录中的脚本。 这是我的“菜单”的一部分,只是为了澄清:

#######

Title: Test script 1
Description: Test script 1
To execute: 0

#######

Title: Test script 2
Description: Test script 2
To execute: 1

#######

我有一个名为array的数组,其中包含脚本的名称,其索引对应于“to execute”下的打印值。现在,我正在使用case语句来处理输入并提供退出选项。

case $REPLY in 
     [Ee]) clear
           exit;;
     [[:digit:]] $scriptDirectory/${array[$REPLY]}

但是,[[:digit:]]表达式仅匹配0-9。我需要一个适用于匹配0-999或类似的case语句的正则表达式。

4 个答案:

答案 0 :(得分:3)

case仅使用globs(也就是文件名扩展模式),而不是正则表达式。

您可以使用shopt -s extglob设置extended glob,然后您可以使用+()来匹配一个或多个事件:

shopt -s extglob

case $REPLY in 
     [Ee]) clear
           exit;;
     +([[:digit:]])) $scriptDirectory/${array[$REPLY]};;
esac

注意:我在第二种情况模式后添加了遗漏),并在同一行末尾缺少;;。还添加了esac缺少的声明。

更新:

如果您只想匹配0到999之间的数字,请尝试:

     [0-9]?([0-9])?([0-9]))  $scriptDirectory/${array[$REPLY]};;

此处使用字符范围,因为我发现它更具可读性。结果将是相同的。

答案 1 :(得分:2)

我发现的最简单的方法是bash:

^(1000|[0-9]{1,3})$

将此正则表达式=~运算符(将右侧的字符串解释为扩展正则表达式)结合使用,您可以构建一个简单的测试。 (输入为"$1"

if [[ $1 =~ ^(1000|[0-9]{1,3})$ ]]; then
    echo "0 <= $1 <= 1000 (1)"
else
    echo "$1 - invalid number"
fi

示例使用/输出

$ for i in -10 -1 0 1 10 100 999 1000 1001; do ./zero1thousand.sh $i; done
-10 - invalid number
-1 - invalid number
0 <= 0 <= 1000
0 <= 1 <= 1000
0 <= 10 <= 1000
0 <= 100 <= 1000
0 <= 999 <= 1000
0 <= 1000 <= 1000
1001 - invalid number

答案 2 :(得分:0)

在这个简单的例子中,我建议您使用如下所示的内容:

REPLY="$1" # I assumed there is an argument to the script

if [[ $1 =~ ^[[:digit:]]+$ ]]
then
   padded_REPLY=$(printf "%04d" "$REPLY")
   #echo "Padded reply : $padded_REPLY"
else
   padded_REPLY="$REPLY"
   echo "Padded reply : $padded_REPLY"
fi

regexp1="^[[:digit:]]{4}$" #checks padded_REPLY is in the range 0000 to 1000 
#the input is padded 
regexp2="[eE]+$"

if [[ "$padded_REPLY" =~ $regexp1 ]]
then
   if [ "$REPLY" -le 1000 ] #checking script exist
   then
     echo "$REPLY" # I just echoed, you do the stuff below
     #"$scriptDirectory/${array[$REPLY]}"
   else
     echo "Scripts are numbered from 0 to 1000"
   fi       
elif [[ "$padded_REPLY" =~ $regexp2 ]]
then
  clear
  exit
fi

但建议getopts用于更智能的参数管理。

答案 3 :(得分:0)

尝试一下:

case $REPLY in
  [Ee]) 
        clear
        exit 0;;

  [[:digit:]]|[[:digit:]][[:digit:]]|[[:digit:]][[:digit:]][[:digit:]]|1000) 
        $scriptDirectory/${array[$REPLY]}
        exit 0;;
esac

所涉及的模式列表匹配1位数或2位数或3位数或1000位。

case一起使用的模式在开放组的Pattern Matching Notation中有所描述。

请注意,这不是正则表达式。

正则表达至少有一件事;这是[]RE Bracket Expression)。它用于匹配单个字符。因此,[[:digit:]]有效。它匹配单个字符,可以是任何数字。

要匹配多个数字,需要连接与单个字符匹配的多个模式,例如:使用[[:digit:]][[:digit:]]匹配2位数。

|可用于匹配多个模式。要匹配0到99之间的数字,即一位数或2位数,请使用[[:digit:]]|[[:digit:]][[:digit:]]