bash 测试字符串是否为金额

bash 测试字符串是否为金额

我正在使用一个有点自由格式的 csv 文件,需要有效地查找费用条目。我更好的解决方案是测试每一行中特定列的数量。我尝试了以下方法(GNU bash,版本 5.0.17),但它不起作用(没有返回“是美元金额”):

#!/bin/bash
input=$1
if [[ $input == [\$]?[0-9][\,]?[0-9]*[\.]?[0-9]{2}?$ ]]
then
echo "Is a dollar amount"
else
echo "Is NOT a dollar amount"
fi

我尝试过美元符号、逗号和句点刚刚转义(没有括号),但这也不起作用。我单引号包含美元符号的参数(必须)。我将 == 更改为 =~ 并且太多可能性报告“是美元金额”。在网络上搜索类似的东西几乎是不可能的。我究竟做错了什么?我以为我写的意思是:

  • 前导美元符号是可选的 - [$]?
  • 至少需要一位数字 - [0-9]
  • 逗号是可选的 - [,]?
  • 任何数量的附加数字都是可接受的 - [0-9]*
  • 句点是可选的 - [.]?
  • 可以有两个附加数字,但这也是可选的 - [0-9]{2}?
  • 最后两位数字后没有任何内容 - $

答案1

您可能想使用=~运算符而不是==进行测试,并且不能使用?after {2}

说“没有或两位数字”的正确方法是([0-9]{2})?

你最终得到的是

if [[ $input =~ ^\$?[0-9],?[0-9]*\.?([0-9]{2})?$ ]]; then ...; fi

在这里,我还将表达式锚定到行的开头,^并删除了一些不必要的方括号。

如果字符串中可选的部分不是独立可选的,您可能需要将这些部分放在括号中,例如,

if [[ $input =~ ^\$?[0-9](,[0-9]+)?(\.[0-9]{2})?$ ]]; then ...; fi

如果有逗号,则要求逗号后至少有一位数字;如果是点,则要求点后至少有两位数字。

答案2

感谢@they 的上述帖子让我找到了答案:

if [[ $input =~ ^\$?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{2})?$ ]]

我发现我犯了很多错误。我将上面的脚本称为“测试”并尝试了几种变体(见下文),它们都按预期响应。

以下报道“是美元金额”

  • ./测试1
  • ./测试75
  • ./测试453
  • ./测试'$453'
  • ./测试1,234
  • ./测试1,234.89
  • ./测试1,234,657.89

以下报道“不是美元金额”

  • ./测试1a234,657.89
  • ./test 1,234.657.89(注意两个句点)
  • ./test 1,234,657.9(缺少美分数字)

相关内容