【问题标题】:Bash regex to match quoted stringBash 正则表达式以匹配引用的字符串
【发布时间】:2017-12-14 10:59:24
【问题描述】:

我正在尝试提出一个正则表达式,我可以使用它来匹配由单引号或双引号括起来的字符串。正则表达式应匹配以下所有字符串:

"ABC&VAR#"
'XYZ'
"ABC.123"
'XYZ&VAR#123'

这是我目前所拥有的:

^([\x22\x27]?)[\w.&#]+\1$

\x22代表"字符,\x27是'字符。

这适用于RegExr,但不适用于使用 =~ 运算符的 Bash 比较。我忽略了什么?

更新:问题是我的正则表达式使用Bash 不支持的PCRE 语法的两个功能:\w 原子和反向引用。感谢Inian 提醒我这一点。我决定使用 grep -oP 而不是 Bash 内置的 =~ 运算符,这样我就可以利用 PCRE 的优势。请参阅下面的评论。

【问题讨论】:

  • \w 是一个 perl 正则表达式原子,bash 使用 POSIX 扩展正则表达式代替
  • 查看了各种替代方案,我决定采用这样的方法:if [[ $(echo "${string}" | grep -oP $regex >/dev/null; echo $?) -eq 0 ]]; then... 这样我就可以使用 PCRE 细节,例如 \w 和反向引用。

标签: regex bash


【解决方案1】:

BASH 正则表达式不支持反向引用。在 BASH 中,您可以这样做。

arr=('"ABC&VAR#"' "'XYZ'" '"ABC.123"' "'XYZ&VAR#123'" "'foobar\"")

re="([\"']).*(['\"])"

for s in "${arr[@]}"; do
    [[ $s =~ $re && ${BASH_REMATCH[1]} = ${BASH_REMATCH[2]} ]] && echo "matched $s"
done

额外检查${BASH_REMATCH[1]} = ${BASH_REMATCH[2]} 以确保我们有相同的开盘价和收盘价。

输出:

matched "ABC&VAR#"
matched 'XYZ'
matched "ABC.123"
matched 'XYZ&VAR#123'

【讨论】:

  • 我们可以只使用[[ $line =~ \'[[:graph:]]+\' || $line =~ \"[[:graph:]]+\" ]]吗?如果是这样,我使用的方式是否可以进一步简化
  • 是的@Inian 2个不同的正则表达式也可以按照你的建议使用。但是使用单个正则表达式通常更有效。不过,使用[[:graph:]]+ 是个好主意。
【解决方案2】:

您可以对 egrep 使用正则表达式 (\"|\').*(\"|\')。 这是我的示例,说明它是如何工作的:

a="\"ABC&VAR#\""
b="'XYZ'"
c="\"ABC.123\""
d="'XYZ&VAR#123'"
echo "Line correct: ${a} and ${b} and ${c} and ${d}"
if [ `echo "${a}" | egrep "(\"|\').*(\"|\')"` -o `echo "${b}" | egrep "(\"|\').*(\"|\')"` -o `echo "${c}" | egrep "(\"|\').*(\"|\')"` -o `echo "${d}" | egrep "(\"|\').*(\"|\')"` ]
then 
    echo "Found"
else 
    echo "Not Found"
fi

输出:

Line correct: "ABC&VAR#" and 'XYZ' and "ABC.123" and 'XYZ&VAR#123'
Found

为了避免太长的 if 表达式,例如使用数组作为变量。 在这种情况下,您将拥有类似的东西:

a="\"ABC&VAR#\""
b="'XYZ'"
c="\"ABC.123\""
d="'XYZ&VAR#123'"

arr=( "\"ABC&VAR#\"" "'XYZ'" "\"ABC.123\"" "'XYZ&VAR#123'" )

for line in "${arr[@]}"
do
    [ `echo "${line}" | egrep "(\"|\').*(\"|\')"` ] && echo "Found match" || echo "Matches not found"
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    • 2012-06-05
    相关资源
    最近更新 更多