shell 脚本中可以使用哪些正则表达式方法来验证输入?

shell 脚本中可以使用哪些正则表达式方法来验证输入?
#!/bin/sh

re="\/$"

if [ $1 =~ $re ]; then
        echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
        exit 1
fi

执行./file.sh hello/结果为[: 29: hello: unexpected operator

看来这个正则表达式方法对于 shell 脚本来说是不正确的。

答案1

标准test命令也称为[没有=~运算符。现在大多数 shell 都内置了该命令。

Korn shell 引入了具有替代语法和不同解析规则的[[...]]构造(不是命令)。[[

zshbash在一定程度上复制了它,但有限制和许多差异,但从未标准化,因此不应在可移植sh脚本中使用。

ksh93总是有办法将扩展的正则表达式转换为它的通配符:

pattern=${ printf %P "regexp"; }

然后你可以这样做:

[[ $var = $pattern ]]

之后 (2001 年 ksh93l)它还在其 glob 中合并了正则表达式,就像~(E)regex扩展正则表达式的语法一样,因此您可以执行以下操作:

[[ $var = ~(E)regex ]]

这种模式匹配仅适用于[[...]]构造 or case,不适用于[命令。

zsh为其[命令添加了正则表达式匹配运算符,并[[...]]在 2001 年首次使用pcre模块添加了正则表达式匹配运算符。语法最初是[ string -pcre-match regex ]or [[ string -pcre-match regex ]]

bash=~bash 3.0添加了一个运算符(2004 年)。使用扩展正则表达式。不久之后 ksh93 和 zsh 也添加了这一点(同样存在差异)。

ksh93bash-3.2以上(当该compat31选项未启用时)使用引号逃脱regexp 运算符会导致各种混乱(并且在 ksh93 中存在很多错误),这意味着它不能与[那里的命令以相同的方式使用。zsh没有这个问题(引号用于 shell 引用,反斜杠像往常一样转义正则表达式运算符),因此该运算符在的命令=~中工作(尽管它本身需要引号,因为它是 中的文件名扩展运算符)。zsh[=foozsh

yash没有,[[...]]但它的[命令有一个=~运算符(使用 ERE)并且按您的预期工作(如zsh's)。

2023年编辑)[[...]]在 2.49 (2018) 中添加了对 yash 的支持,并且=~在引用方面与 bash 类似。

无论如何, 和 都不[[...]]是POSIX 运算符,也不应该在脚本=~中使用。sh对字符串进行正则表达式匹配的标准命令是expr

if expr "x$var" : "x$regex" > /dev/null; then...

请注意,expr正则表达式是在开始时锚定的,您需要这个x技巧来避免运算$var符值出现问题exprexpr使用基本正则表达式,而不是扩展正则表达式。

然而,大多数时候,您不需要正则表达式,因为简单的 shell 模式匹配对于大多数情况来说就足够了:

case $var in
  (pattern) echo matches
esac

答案2

更改#!/bin/sh#!/bin/bash, 并使用双括号代替:

if [[ $1 =~ $re ]]; then

这是扩展测试命令,与(常规)测试命令相反。=~只能与[[ ... ]]版本一起使用,并且需要 Bash 3.0 或更高版本。

答案3

bash旧测试中[不支持正则表达式。您必须使用新的测试[[来代替:

re="\/$"

if [[ $1 =~ $re ]]; then
        echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
        exit 1
fi

你可以看到更多这里

您还需要将#!/bin/shshebang 行更改为#!/bin/bash

相关内容