检查字符串是否与Bash脚本中的正则表达式匹配

Pet*_*jem 187 regex bash shell scripting

我的脚本收到的一个参数是以下格式的日期:yyyymmdd.

我想检查一下是否有一个有效的日期作为输入.

我怎样才能做到这一点?我试图使用正则表达式:[0-9]\{\8}

fed*_*qui 285

你可以说:

[[ $date =~ ^[0-9]{8}$ ]] && echo "yes"
Run Code Online (Sandbox Code Playgroud)

或者更准确:

[[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes"
#           |^^^^^^^^ ^^^^^^ ^^^^^^  ^^^^^^ ^^^^^^^^^^ ^^^^^^ |
#           |   |     ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^ |
#           |   |          |                   |              |
#           |   |           \                  |              |
#           | --year--   --month--           --day--          |
#           |          either 01...09      either 01..09     end of line
# start of line            or 10,11,12         or 10..29
#                                              or 30, 31
Run Code Online (Sandbox Code Playgroud)

也就是说,您可以在bash中定义匹配所需格式的正则表达式.这样你可以做到:

[[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match"
Run Code Online (Sandbox Code Playgroud)

请注意,这是基于Aleks-Daniel Jakimenko 在bash中的用户输入日期格式验证中的解决方案.


在其他shell中,您可以使用grep.如果您的shell符合POSIX,请执行

(echo "$date" | grep -Eq  ^regex$) && echo "matched" || echo "did not match"
Run Code Online (Sandbox Code Playgroud)

鱼类中,不符合POSIX标准,你可以这样做

echo "$date" | grep -Eq "^regex\$"; and echo "matched"; or echo "did not match"
Run Code Online (Sandbox Code Playgroud)

  • 我知道这一点,但我也想考虑到谁在询问他们与bash有多远.如果我们提供非常复杂的条件,他们就不会学到任何东西,只要再有疑问就回来.我更喜欢给出一个更容易理解的答案. (19认同)
  • @ Aleks-DanielJakimenko我再次阅读了这篇文章,现在我同意最好使用bash正则表达式.感谢您指出了良好的方向,更新了答案. (6认同)
  • 嘿.嗯,唯一的学习方法是阅读很多优秀的代码.如果您提供易于理解但不建议使用的虚假代码 - 这是一种不好的教学方式.另外我很确定那些刚刚开始学习bash(可能已经知道其他一些语言的部分)的人会比使用``-E``标志的``grep``命令更容易理解正则表达式的bash语法. (5认同)
  • Upvote,允许比OP问题稍微使用它,例如.. (4认同)
  • 使用grep的@ Aleks-DanielJakimenko似乎是最好的选择,如果你使用`sh`,`fish`或其他装备较少的shell. (3认同)

ali*_*sav 41

在bash版本3中,您可以使用'=〜'运算符:

if [[ "$date" =~ "[0-9]\{8\}" ]]; then
    echo "Valid date"
else
    echo "Invalid date"
fi
Run Code Online (Sandbox Code Playgroud)

参考:http://tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF

注意:从Bash版本3.2开始,不再需要在双括号[[]]内的匹配运算符中引用

  • 你不应该在正常表达时使用char吗?因为当我使用expresion时不起作用 (19认同)

Dja*_*nny 29

测试字符串是否正确日期的好方法是使用命令日期:

if date -d "${DATE}" >/dev/null 2>&1
then
  # do what you need to do with your date
else
  echo "${DATE} incorrect date" >&2
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

  • 高度评价您的答案,因为它让日期函数处理日期而不是容易出错的正则表达式' (8认同)

V.7*_*V.7 6

除了=~Bash 运算符的其他答案 -扩展正则表达式(ERE)

awk这是and egrep(或grep -E
以及 Bash运算符使用的语法[[ ... =~ ... ]]

例如,支持在多个参数中提供多个测试的函数:

#!/bin/bash

#-----------#
# Functions #
#-----------#

function RT
{
    declare __line;

    for __line in "${@:2}";
    do
        if ! [[ "$__line" =~ $1 ]];
        then
            return 1;
        fi
    done

    return 0;
}

#-----------#
# Main      #
#-----------#

regex_v='^[0-9]*$';
value_1_v='12345';
value_2_v='67890';

if RT "$regex_v" "$value_1_v" "$value_2_v";
then
    printf 'Valid';
else
    printf 'Invalid';
fi
Run Code Online (Sandbox Code Playgroud)

描述

功能RTRegex Test

# Declare a local variable for a loop.

declare __line;
Run Code Online (Sandbox Code Playgroud)
# Loop for every argument's value except the first - regex rule

for __line in "${@:2}";
Run Code Online (Sandbox Code Playgroud)
# Test the value and return a **non-zero** return code if failed.
# Alternative: if [[ ! "$__line" =~ $1 ]];

if ! [[ "$__line" =~ $1 ]];
Run Code Online (Sandbox Code Playgroud)
# Return a **zero** return code - success.

return 0;
Run Code Online (Sandbox Code Playgroud)

主要代码

# Define arguments for the function to test

regex_v='^[0-9]*$'; # Regex rule
value_1_v='12345'; # First value
value_2_v='67890'; # Second value
Run Code Online (Sandbox Code Playgroud)
# A statement which runs the function with specified arguments
# and executes `printf 'Valid';` if succeeded, else - `printf 'Invalid';`

if RT "$regex_v" "$value_v";
Run Code Online (Sandbox Code Playgroud)

应该可以指向失败的参数,例如,通过将计数器附加到循环并将其值打印到stderr.

有关的

运算符右侧的引号=~使其成为string,而不是RegularExpression

来源