正则表达式"字符串的开始"锚不工作

时间:2017-02-01 01:43:16

标签: regex bash

我现在正在使用的正则表达式如下:

^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$

我试图匹配所有浮点数,但仅限于数字。例如,以下内容应匹配:

  • 6.0
  • 1.22E3
  • -2
  • 2.99999e-12

但是,以下内容不应匹配:

  • somestring /////// 6.0

我已在this validation site上测试了上述正则表达式,并且按预期工作。但是,在我的bash脚本中运行它时,一切都没有匹配。

这是我的bash代码:

if [[ "$VAL" =~ ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$ ]]
    then
        echo $VAL, "is a number"
    else
        echo $VAL, "is not a number"
fi

我尝试删除锚点,它匹配任何包含浮点数的字符串。但是,字符串如" ////// 6.00007"比赛。 $ anchor按预期工作;但是,^没有。

如果您有任何解决此问题的建议,请与我们联系。

谢谢!

修改1

删除了不好的例子

修改2

我按照@lurker的建议在自己的foo.sh运行正则表达式,代码按照我的测试用例运行。所以我看看与正则表达式进行比较的内容。当我echo编辑被比较的东西时,一切看起来都很好,所以对于为什么正则表达式不匹配没有任何意义。

然后我开始怀疑echo由于某种原因未在$VAL中显示实际上的内容。

所以我运行了这个:NEWVAL=(echo $VAL)作为临时解决方法,直到我能弄明白发生了什么。

2 个答案:

答案 0 :(得分:1)

你的正则表达式不允许指数中的小数。指数可能包含小数,因此您需要更改“数字”的定义,或者需要更改正则表达式。

假设后者,这是一个更正(Bash 4.4):

echo "6.0
1.22E3.7
-2
2.99999e-0.0001
somestring///////6.0" >/tmp/f1.txt

while IFS= read -r line || [[ -n $line ]]; do 
    if [[ "$line" =~ ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[-+]?[0-9]*\.?[0-9]+)?$ ]]
        then
            echo $line, "is a number"
        else
            echo $line, "is not a number"
    fi
done < /tmp/f1.txt  

打印:

6.0, is a number
1.22E3.7, is a number
-2, is a number
2.99999e-0.0001, is a number
somestring///////6.0, is not a number

你应该知道,大多数人认为列表中只有两个合法数字是6.0-2。简单的测试方法是使用awk

$ awk '$1+0==$1{print $0 " is a number"; next} {print $0 " not a number"}' /tmp/f1.txt
6.0 is a number
1.22E3.7 not a number
-2 is a number
2.99999e-0.0001 not a number
somestring///////6.0 not a number

awk用于将字符串转换为float的相同C语言函数被许多其他语言(Ruby,Perl,Python,C,C ++,Swift等)使用,所以如果你考虑你的格式有效的,您可能也会编写自己的转换例程。

例如,在大多数语言中,您可以输入10**1.5作为合法的浮动字面值。我知道的语言在e

形式的字符串中的'xx.zzEyy.y'后面接受十进制数字

答案 1 :(得分:0)

事实证明,我与我的正则表达式进行比较的变量在它们上面引出了新的线条(例如"\n2.3333"),这些线条被echo剥夺了。所以,当我用echo向屏幕显示值时,我会看到我的变量的剥离版本,这与正则表达式没有比较。

获得的经验教训:echo并非始终值得信赖。根据@ CharlesDuffy的评论,使用以下其中一项来查看变量中的实际declare -p varnameprintf '%q\n' "$varname"但是 < strong>不 使用echo $varname