这看起来很简单,但事实并非如此:
[[ "1234+5678" =~ [0-9]+(\s*(\-|\*)\s*[0-9]+)* ]] && echo $?
返回一个0
.然而,实际上不应该这样做,因为只允许减号 ( -
) 和乘法 ( *
) 运算符。另外,我在网上找到了一些正则表达式工具并尝试匹配此模式:结果是空字符串。 (如预期)
在散文中,这扩展正则表达式如下:
- 查找号码(必填)
- 检查是否有一些空白
- 运算符必须是 a
-
或 a*
- 检查是否有一些空白(再次)
- 查找另一个数字(如果前面有运算符,则必须存在)
此外,括号中的表达式后面的星号表示第二到第 n 个运算符数字对是可选的。
我这里的想法错误在哪里?
答案1
如果没有标记,正则表达式(右侧部分)可以匹配任何部分的字符串。所以你的变体匹配1234
。为了满足要求,您必须使用标记:
[[ "1234+5678" =~ ^[0-9]+(\s*(\-|\*)\s*[0-9]+)*$ ]] ; echo $?
更短(如果你愿意的话):
[[ "1234+5678" =~ ^[0-9\ *-]+*$ ]] ; echo $?
答案2
您的表达式返回 0,因为它与第一个数字匹配。锚定正则表达式以使其执行您想要的操作:
[[ "1234+5678" =~ ^[0-9]+( *(-|\*) *[0-9]+)*$ ]] && echo $?
附注:(1) 您不需要引用-
,并且 (2)\s
不被识别为 ERE。
答案3
[[ "1234+5678" =~ [0-9]+(\s*(\-|\*)\s*[0-9]+) ]] ; echo $?
*
正则表达式末尾的正则表达式运算符允许 () 内的表达式任意次数重复,也不允许重复。所以你从一开始就匹配[0-9]+,其余的都是可选的。
如果删除*
或将其替换为 a,则+
表达式将按预期返回。
此外,括号中的表达式后面的星号表示第二到第 n 个运算符数字对是可选的。
这就是错误:这*
意味着any 运算符是选项。使用+
运算符!
好吧,这不是答案,但您可以使用表达式并查看结果是否为空:
echo "1234*5678"|sed 's/[0-9]\+\([ \*\-][0-9]\+\)*//'