当前位置:  开发笔记 > 编程语言 > 正文

测试string是否为有效整数

如何解决《测试string是否为有效整数》经验,为你挑选了5个好方法。

我正在尝试做一些常见的事情:在shell脚本中解析用户输入.如果用户提供了有效的整数,则脚本会执行一项操作,如果无效,则执行其他操作.麻烦的是,我还没有找到一种简单(而且相当优雅)的方式 - 我不想用char来区分char.

我知道这一定很容易,但我不知道如何.我可以用十几种语言来做,但不是BASH!

在我的研究中,我发现了这个:

正则表达式,用于测试字符串是否包含基数为10的有效实数

其中有一个关于正则表达式的答案,但据我所知,这是C(以及其他)中可用的函数.尽管如此,它看起来像是一个很好的答案,所以我用grep尝试了它,但是grep不知道该怎么做.我试过-P在我的盒子上意味着把它当作PERL regexp - nada.Dash E(-E)也没有用.并且-F都没有.

为了清楚起见,我正在尝试这样的东西,寻找任何输出 - 从那里,我将破解脚本以利用我得到的任何东西.(IOW,我期待一个不合格的输入在有效行重复时不返回任何内容.)

snafu=$(echo "$2" | grep -E "/^[-+]?(?:\.[0-9]+|(?:0|[1-9][0-9]*)(?:\.[0-9]*)?)$/")
if [ -z "$snafu" ] ;
then
   echo "Not an integer - nothing back from the grep"
else
   echo "Integer."
fi

有人请说明这是最容易做到的吗?

坦率地说,在我看来,这是TEST的缩影.它应该有这样的旗帜

if [ -I "string" ] ;
then
   echo "String is a valid integer."
else
   echo "String is not a valid integer."
fi

Ignacio Vazq.. 171

[[ $var =~ ^-?[0-9]+$ ]]

^表示输入模式的开始

-是字符" - "

?意思是"0或前述的1(-)"

+意思是"1或多个前述的([0-9])"

$指示输入图案的端部

因此正则表达式匹配可选-(对于负数的情况),后跟一个或多个十进制数字.

参考文献:

http://www.tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF

"+"表示"前面的1个或多个","$"表示输入模式的结束.所以正则表达式匹配一个可选的`-`后跟一个或多个十进制数字. (10认同)

谢谢伊格纳西奥,我会在一秒钟内尝试一下.你介意解释一下,这样我可以学到一点吗?我收集它读取,"在字符串的开头(^),减号( - )是可选的(?),后跟0到9之间的任意数量的字符,包括"......然后可能+ $是吗?谢谢. (3认同)


小智.. 61

哇......这里有很多好的解决方案!在上述所有解决方案中,我同意@nortally使用-eq一个班轮是最酷的.

我正在运行GNU bash,版本4.1.5(Debian).我也在ksh上检查了这个(SunSO 5.10).

这是我的检查版本是否$1为整数:

if [ "$1" -eq "$1" ] 2>/dev/null
then
    echo "$1 is an integer !!"
else
    echo "ERROR: first parameter must be an integer."
    echo $USAGE
    exit 1
fi

这种方法也考虑了负数,其他一些解决方案会产生错误的否定结果,并且它将允许前缀"+"(例如+30),这显然是一个整数.

结果:

$ int_check.sh 123
123 is an integer !!

$ int_check.sh 123+
ERROR: first parameter must be an integer.

$ int_check.sh -123
-123 is an integer !!

$ int_check.sh +30
+30 is an integer !!

$ int_check.sh -123c
ERROR: first parameter must be an integer.

$ int_check.sh 123c
ERROR: first parameter must be an integer.

$ int_check.sh c123
ERROR: first parameter must be an integer.

解释后,Ignacio Vazquez-Abrams提供的解决方案也很整洁(如果你喜欢正则表达式).但是,它不会处理带+前缀的正数,但可以很容易地修复如下:

[[ $var =~ ^[-+]?[0-9]+$ ]]

你的解决方案和正则表达式之间有一个显着的区别:整数的大小被检查为bash限制(在我的计算机上它是64位).此限制未达到正则表达式解决方案.因此,对于64位计算机上的数字严格大于9223372036854775807,您的解决方案将失败. (2认同)

正如我最近发现的那样,[有些警告](http://stackoverflow.com/a/808740/1858225). (2认同)


tripleee.. 26

这里的聚会迟到了.我非常惊讶没有一个答案提到最简单,最快速,最便携的解决方案; 该case声明.

case ${variable#[-+]} in
  *[!0-9]* | '') echo Not a number ;;
  * ) echo Valid number ;;
esac

在比较之前修剪任何符号感觉有点像黑客,但这使得case语句的表达式变得更加简单.



1> Ignacio Vazq..:
[[ $var =~ ^-?[0-9]+$ ]]

^表示输入模式的开始

-是字符" - "

?意思是"0或前述的1(-)"

+意思是"1或多个前述的([0-9])"

$指示输入图案的端部

因此正则表达式匹配可选-(对于负数的情况),后跟一个或多个十进制数字.

参考文献:

http://www.tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF


"+"表示"前面的1个或多个","$"表示输入模式的结束.所以正则表达式匹配一个可选的`-`后跟一个或多个十进制数字.
谢谢伊格纳西奥,我会在一秒钟内尝试一下.你介意解释一下,这样我可以学到一点吗?我收集它读取,"在字符串的开头(^),减号( - )是可选的(?),后跟0到9之间的任意数量的字符,包括"......然后可能+ $是吗?谢谢.

2> 小智..:

哇......这里有很多好的解决方案!在上述所有解决方案中,我同意@nortally使用-eq一个班轮是最酷的.

我正在运行GNU bash,版本4.1.5(Debian).我也在ksh上检查了这个(SunSO 5.10).

这是我的检查版本是否$1为整数:

if [ "$1" -eq "$1" ] 2>/dev/null
then
    echo "$1 is an integer !!"
else
    echo "ERROR: first parameter must be an integer."
    echo $USAGE
    exit 1
fi

这种方法也考虑了负数,其他一些解决方案会产生错误的否定结果,并且它将允许前缀"+"(例如+30),这显然是一个整数.

结果:

$ int_check.sh 123
123 is an integer !!

$ int_check.sh 123+
ERROR: first parameter must be an integer.

$ int_check.sh -123
-123 is an integer !!

$ int_check.sh +30
+30 is an integer !!

$ int_check.sh -123c
ERROR: first parameter must be an integer.

$ int_check.sh 123c
ERROR: first parameter must be an integer.

$ int_check.sh c123
ERROR: first parameter must be an integer.

解释后,Ignacio Vazquez-Abrams提供的解决方案也很整洁(如果你喜欢正则表达式).但是,它不会处理带+前缀的正数,但可以很容易地修复如下:

[[ $var =~ ^[-+]?[0-9]+$ ]]


你的解决方案和正则表达式之间有一个显着的区别:整数的大小被检查为bash限制(在我的计算机上它是64位).此限制未达到正则表达式解决方案.因此,对于64位计算机上的数字严格大于9223372036854775807,您的解决方案将失败.
正如我最近发现的那样,[有些警告](http://stackoverflow.com/a/808740/1858225).

3> tripleee..:

这里的聚会迟到了.我非常惊讶没有一个答案提到最简单,最快速,最便携的解决方案; 该case声明.

case ${variable#[-+]} in
  *[!0-9]* | '') echo Not a number ;;
  * ) echo Valid number ;;
esac

在比较之前修剪任何符号感觉有点像黑客,但这使得case语句的表达式变得更加简单.


我希望每次因为愚蠢而回到这个问题,我都可以投票一次.我研究了一种简单但符合POSIX标准的解决方案,它埋在底部.
也许你应该照顾空字符串:````''|*[!0-9]*)````
顺便说一句:这是此语法记录:http://tldp.org/LDP/abs/html/string-manipulation.html

4> ephemient..:

为了便于预先Bash 3.1(当=~引入测试时),使用expr.

if expr "$string" : '-\?[0-9]\+$' >/dev/null
then
  echo "String is a valid integer."
else
  echo "String is not a valid integer."
fi

expr STRING : REGEX搜索在STRING开始时锚定的REGEX,回显第一组(或匹配的长度,如果没有)并返回成功/失败.这是旧的正则表达式语法,因此是多余的\. -\?表示"可能-",[0-9]\+表示"一个或多个数字",$表示"字符串结尾".

Bash也支持扩展的globs,但我不记得从哪个版本开始.

shopt -s extglob
case "$string" of
    @(-|)[0-9]*([0-9]))
        echo "String is a valid integer." ;;
    *)
        echo "String is not a valid integer." ;;
esac

# equivalently, [[ $string = @(-|)[0-9]*([0-9])) ]]

@(-|)表示" -或没有",[0-9]表示"数字",*([0-9])表示"零或更多数字".



5> nortally..:

我喜欢使用-eq测试的解决方案,因为它基本上是一个单行.

我自己的解决方案是使用参数扩展来丢弃所有数字,看看是否还有什么东西.(我还在使用3.0,没有使用过[[expr之前,但很高兴见到它们.)

if [ "${INPUT_STRING//[0-9]}" = "" ]; then
  # yes, natural number
else
  # no, has non-numeral chars
fi


这可以使用`[-z"$ {INPUT_STRING // [0-9]}"]`进一步改进,但是非常好的解决方案!
推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有