【问题标题】:Regular Expression to follow a specific pattern遵循特定模式的正则表达式
【发布时间】:2016-12-03 02:07:52
【问题描述】:

我正在尝试确保我的 shell 脚本的输入遵循 Name_Major_Minor.extension 格式

其中名称是任意数量的数字/字符/“-”后跟“_”

Major 是后跟“_”的任意位数

Minor 是后跟“.”的任意位数

扩展名是任意数量的字符,后跟文件名的结尾。

我相当肯定我的正则表达式只是稍微搞砸了。我当前运行的任何文件都评估为“是”,但如果我添加“[A-Z]$”而不是“*$”,它总是评估为“否”。正如你可能知道的那样,正则表达式把我搞糊涂了..

if echo $1 | egrep -q [A-Z0-9-]+_[0-9]+_[0-9]+\.*$
then
    echo "yes"
else
    echo "nope"
    exit
fi

编辑:意识到我错过了“次要”的模式。加了之后还是不行。

【问题讨论】:

    标签: regex bash shell grep


    【解决方案1】:

    使用 =~ 运算符

    Bash 通过其=~ operator 支持正则表达式匹配,在这种特殊情况下不需要egrep

    if [[ "$1" =~ ^[A-Za-z0-9-]+_[0-9]+_[0-9]+\..*$ ]]
    

    正则表达式中的错误

    正则表达式中的\.*$ 序列表示“零个或多个”。您的意思可能是“一个点和后面的一些字符”,即\..*$

    您的正则表达式仅匹配字符串的结尾 ($)。您可能想要匹配整个字符串。要匹配整个字符串,请使用 ^ 锚来匹配行首。

    转义命令行参数

    如果您仍想使用egrep,您应该转义它的参数,因为您应该转义任何命令行参数以避免重新解释特殊字符,或者将参数用单引号或双引号括起来,例如:

    if echo "$1" | egrep -q '^[A-Za-z0-9-]+_[0-9]+_[0-9]+\..*$'
    

    使用 printf 代替 echo

    Don't use echo,因为它的行为被认为是不可靠的。请改用printf

    printf '%s\n' "$1"
    

    【讨论】:

      【解决方案2】:

      试试这个正则表达式:^[A-Za-z0-9-]+(?:_[0-9]+){2}\..+$

      • [A-Za-z0-9-]+ 匹配 Name
      • _[0-9]+ 匹配 _ 后跟一位或多位数字
      • (?:...){2} 匹配组两次:_Major_Minor
      • \..+ 匹配一个句点后跟一个或多个字符

      您的正则表达式中的问题似乎以\.* 结尾,它与句点\. 匹配任意多次,see here[A-Z0-9-] 也只会匹配大写字母,可能不是你想要的。

      【讨论】:

      • ./version_buddy.sh: 第 4 行:`if echo $1 | egrep -q ^[A-Za-z0-9-]+(?:_[0-9]+){2}\..+$' 我得到这个错误
      • 我想通了。我添加了您的“a-z”(我没有意识到它区分大小写)。最后我在 $ 之前添加了一个 *。
      • 我的正则表达式可能因为(?:...) 而无法工作,它似乎不受支持,您可以尝试^[A-Za-z0-9-]+(_[0-9]+){2}\..+$.。不要忘记点赞和接受! ;)
      • 使用 POSIX 字符类 [:alnum:] 而不是硬编码 A-Za-z0-9。是的,grep 需要 -P 参数来支持环视和其他 PCRE 构造,但在这种情况下它是不必要的。最后的 +$ 没有做任何有用的事情 - 无论有没有它都会发生相同的匹配。
      • 其实[:alnum:] 也匹配下划线。并且.+$结尾匹配扩展名,是必须的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多