如何在shell脚本中使用正则表达式?

bmvo0sr5  于 2023-02-13  发布在  Shell
关注(0)|答案(3)|浏览(135)

我希望将输入字符串(包含在变量$1中)与表示日期格式MM/DD/YYYYMM-DD-YYYY的正则表达式进行匹配。

REGEX_DATE="^\d{2}[\/\-]\d{2}[\/\-]\d{4}$"
 
echo "$1" | grep -q $REGEX_DATE
echo $?

无论输入字符串是什么,echo $?都返回错误代码1

wf82jlnq

wf82jlnq1#

为了补充现有的有用答案:
在这种情况下,使用**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

但是,请注意,关于使用特定于风格的regex结构(如\d)的警告同样适用:虽然=~支持ERE(* 扩展 * 正则表达式),但它也支持 * 主机平台的特定扩展 *--这是Bash的行为依赖于平台的罕见情况。
要保持可移植性(在Bash的上下文中),请坚持POSIX ERE规范。
注意,=~甚至允许定义捕获组(括号中的子表达式),稍后可以通过Bash的特殊数组变量${BASH_REMATCH[@]}访问这些捕获组的匹配项。
进一步说明:

  • $kREGEX_DATE被使用为 * unquoted *,这对于regex被如此识别是必要的(被引用的部分将被视为 * literal *)。
  • 虽然不总是必要的,但建议先将regex存储在变量中,因为Bash在处理包含\的regex * literal * 时会遇到麻烦。
  • 例如,在Linux上,\<支持匹配字边界,[[ 3 =~ \<3 ]] && echo yes不起作用,但re='\<3'; [[ 3 =~ $re ]] && echo yes起作用。
  • 我将变量名REGEX_DATE更改为kREGEX_DATEk表示一个(概念上的)常量),以确保该名称不是全大写名称,因为应避免使用全大写变量名,以防止与特殊环境和shell变量冲突。
new9mtju

new9mtju2#

我想这就是你想要的

REGEX_DATE='^\d{2}[/-]\d{2}[/-]\d{4}$'

echo "$1" | grep -P -q $REGEX_DATE
echo $?

我使用了-P开关来获取perl正则表达式。

cigdeys3

cigdeys33#

这问题是你正在尝试到使用regex特征不被grep支持.即,你的\d将不再工作.使用这代替:

REGEX_DATE="^[[:digit:]]{2}[-/][[:digit:]]{2}[-/][[:digit:]]{4}$"
echo "$1" | grep -qE "${REGEX_DATE}"
echo $?

要使用{#}样式,您需要-E标志来获取ERE。

相关问题