简单的Bash和RegEx问题

8

我在bash 4.1中使用正则表达式无法正确匹配模式。我已经阅读了一些关于引号与非引号之间差异的信息,但我不认为那是我的问题。

我的目标是检查并确保脚本提供了有效的ID。在这种情况下,有效的ID是由9个数字组成的字符串。据我所知,用于匹配这种模式的正则表达式是\d{9}。因此,以下是我的代码片段来检查:

id=$1       
if [[ $id =~ \d{9} ]]; then
     echo "This is a vaild ID"
else
     echo "This is not a vaild ID"
fi

然后使用以下命令调用脚本:

 ./script 987654321

我有什么明显的遗漏吗?这与IT技术有关。

你应该编辑你的问题并说明为什么你认为它不起作用。你是否到达了else语句?还是遇到了语法错误?祝你好运。 - shellter
3
Bash(v3及以上版本)中的正则表达式不支持\d,您可以使用[0-9][:digit:] POSIX字符类。 - ocodo
1
最完全可移植的方法是使用通配符模式,即 case $id in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) echo fine ;; *) die in anguish;; esac - tripleee
4个回答

9

这个可以用:if [[ $id =~ [[:digit:]]{9} ]] – David W. 11小时前


@David 我在bash上尝试了一下,似乎不起作用。– Vivin Paliath 10小时前


我刚刚写了一个测试程序:

#! /bin/bash

for id in 123456789 12345689 1234567890 987654321
do
    if [[ $id =~ ^[[:digit:]]{9}$ ]]
    then
        echo "$id is 9 digits long"
    else
        echo "$id is bad"
    fi
done

我得到了以下输出:

DaveBook:~ david$ ./test.sh
123456789 is 9 digits long
12345689 is bad
1234567890 is bad
987654321 is 9 digits long
DaveBook:~ david$ 

我正在使用Mac OS X上的BASH 3.2.48和Cygwin上的Bash 4.1.10(4)(哇,Mac版本是那么老?)。我还没有在Linux系统上测试过。
您使用的是哪个版本?您是否将方括号 :digit: 加倍?它必须是[[:digit:]]而不是[:digit:]
我还意识到我需要在那里使用^$锚点,因为您不想匹配foo123456789bar1234567890123456790。这是您遇到的问题吗?
问题是[[:digit:]]应该可以工作。我已经在许多Bash shell脚本中使用它,认为它是相当普遍的。但是,如果您有一个无法工作的BASH shell,我将不得不停止使用它。

我不知道之前我在抽什么,但我现在刚试了一下,它可以运行。我发誓上次尝试时它没有工作,因为那是我尝试的最初的事情之一。 - Vivin Paliath
这正是我在寻找的,谢谢。你有关于查找项目之间等价性的参考文章吗,例如/d和[[:digit:]]?或者man页面是最好的资源? - Gray Race
实际上,最好的资料来源是Perl文档。毕竟,所有扩展正则表达式的内容最初都来自于Perl。请查看perldoc perlre以及有关字符类的部分。 - David W.
非常感谢!如果要指定一个最多9位数字,你会如何做? - Bluz

9

其他人已经回答了,你应该使用[0-9]{9},因为\d不被支持。但是另一个重要的部分是,你必须使用锚点!

^[0-9]{9}$
^将正则表达式锚定到字符串的开头,$将其锚定到结尾。如果您不使用它们,您的正则表达式将匹配包含9个数字序列的每个字符串,例如“abc123456789”,“asdf123456789zui”或“123456789FOOBAR”。

为什么在 :digit: 周围要加上 [[ 和 ]]? - Breako Breako

3

试试这个:

if [[ $id =~ [0-9]{9} ]]; then

看起来bash不认识\d作为[0-9]

Bash使用扩展正则表达式方言,不支持\d

根据ERE的语法(词法约定),转义字符的格式为\SPEC_CHARSPEC_CHAR可以是以下任意一个:

^    .    [    $    (    )    |
*    +    ?    {    \

@David 我测试了一下,现在可以工作了。我不知道第一次尝试时为什么没能工作。 - Vivin Paliath

-2

问题在于\d在被解释之前会被转换为d。尝试进行双重转义。

\d{9} => d{9}
\\d{9} => \d{9}

或者,你可以用引号将它括起来

if [[ $id =~ "\d{9}" ]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接