提取日期的正则表达式

时间:2013-09-10 09:28:16

标签: regex bash sh

我是一个正则表达式,用于匹配表单01/Jan/2000:23:59:59上的日期。我设法使用Notepad ++的正则表达式解释器匹配模式,使用以下正则表达式:

[1-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]

不幸的是,我需要使用bash执行此操作。我担心AWK现在不是一个选择。所以,我试图将上面的正则表达式转换为bash以相同方式解释的东西。到目前为止,我已经想出了这个:

[1-3][0-9]/[A-Z][a-z]\{2\}/(19|20)[0-9]\{2\}:[0-2][0-9]:[0-5][0-9]:[0-5][0-9]

我正在使用的完整命令是

expr "$line" : '\([1-3][0-9]/[A-Z][a-z]\{2\}/(19|20)[0-9]\{2\}:[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\)'

其中$line包含我需要提取日期的字符串。不幸的是我的正则表达式的bash版本不起作用。我尝试过不同的事情,比如逃避/:,但我似乎无法让它发挥作用。我做错了什么?

1 个答案:

答案 0 :(得分:1)

唯一的问题是你的第一个模式[1-3]。它应该是[0-3]。

[[ $DATE =~ [0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9] ]]

此外,在某些早期版本的Bash中,您必须将其存储在变量中:

RE='[0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]'
[[ $DATE =~ $RE ]]

示例:

> DATE='01/Jan/2000:23:59:59'
> [[ $DATE =~ [0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9] ]] && echo Match.
Match.

Bash 3.0:

> echo "$BASH_VERSION"
3.00.0(1)-release
> DATE='01/Jan/2000:23:59:59'
> RE='[0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]'
> [[ $DATE =~ $RE ]] && echo Match.
Match.

如果你想在循环中应用它,你可以这样:

RE='[0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]'
while read -r LINE; do
    [[ $LINE =~ $RE ]] && echo "Match: $LINE"
done < date_list.txt

顺便说一句,如果您想要完全匹配整个单词,请在模式的开头和结尾添加^$

[[ $DATE =~ ^[0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]$ ]]

要在线上提取匹配项,请使用()BASH_REMATCH

[[ $DATE =~ .*([0-3][0-9]/[A-Z][a-z]{2}/(19|20)[0-9]{2}:[0-9]{2}:[0-5][0-9]:[0-5][0-9]).* ]] && echo "${BASH_REMATCH[1]}"