我正在尝试在shell脚本中将字符串与正则表达式匹配。 此字符串是脚本的参数($ 1),它是一个日期(MM / DD / YYYY) 我试图使用的正则表达式是:
^\d{2}[\/\-]\d{2}[\/\-]\d{4}$
它似乎有效,我在几个正则表达式测试网站上试过。
我的shell代码是:
REGEX_DATE="^\d{2}[\/\-]\d{2}[\/\-]\d{4}$"
echo "$1" | grep -q $REGEX_DATE
echo $?
“echo $?”返回1,不管是我放入参数的字符串。
你们有个主意吗?
谢谢!
答案 0 :(得分:33)
补充现有的有用答案:
在这种情况下,使用 Bash自己的正则表达式匹配运算符=~
是一种更快的替代方法,因为您只匹配已存储的单个值在变量中:
set -- '12-34-5678' # set $1 to sample value
kREGEX_DATE='^[0-9]{2}[-/][0-9]{2}[-/][0-9]{4}$' # note use of [0-9] to avoid \d
[[ $1 =~ $kREGEX_DATE ]]
echo $? # 0 with the sample value, i.e., a successful match
但请注意,使用特定于特定风格的正则表达式构造(如\d
的警告同样适用:
虽然=~
支持ERE(扩展正则表达式),但它也支持主机平台的特定扩展 - 它是Bash&的罕见案例#39;行为与平台有关。
为了保持便携性(在Bash的上下文中),请坚持POSIX ERE规范。
请注意,=~
甚至允许您定义捕获组(带括号的子表达式),您可以在以后通过Bash的特殊${BASH_REMATCH[@]}
数组变量访问其匹配项。< / p>
补充说明:
$kREGEX_DATE
使用未加引号,这是正则表达式被识别所必需的(引用的部分将被视为文字)。
虽然并非总是必要,但建议先将正则表达式存储在变量中,因为Bash在包含\
的正则表达式文字时遇到问题。
\<
支持匹配字边界,[[ 3 =~ \<3 ]] && echo yes
不起作用,但re='\<3'; [[ 3 =~ $re ]] && echo yes
可以。我已将变量名称REGEX_DATE
更改为kREGEX_DATE
(k
发出信号(概念)常量),以确保名称不是{&1;}。是一个全大写的名称,因为all-uppercase variable names should be avoided to prevent conflicts with special environment and shell variables。
答案 1 :(得分:10)
我认为这就是你想要的:
REGEX_DATE='^\d{2}[/-]\d{2}[/-]\d{4}$'
echo "$1" | grep -P -q $REGEX_DATE
echo $?
我已经使用-P开关来获取perl正则表达式。
答案 2 :(得分:5)
问题是你正在尝试使用grep不支持的正则表达式功能。即,您的\d
将无效。请改用:
REGEX_DATE="^[[:digit:]]{2}[-/][[:digit:]]{2}[-/][[:digit:]]{4}$"
echo "$1" | grep -qE "${REGEX_DATE}"
echo $?
您需要-E
标记才能获得ERE才能使用{#}
样式。