如何在 Bash 中用正则表达式匹配空格?

How can I match spaces with a regexp in Bash?

我希望下面的代码能够回显 "yes",但它没有。由于某种原因,它与单引号不匹配。为什么?

str="{templateUrl: '}"
regexp="templateUrl:[\s]*'"

if [[ $str =~ $regexp ]]; then
  echo "yes"
else
  echo "no"
fi

去掉正则表达式中的方括号:

regexp="templateUrl:\s*'"

在方括号出现的情况下,\s 被字面解释为匹配 \s 字符,但您的意图显然是与白色 space 字符 class 其中 \s 是 shorthand(因此不需要方括号)。

$ uname -a
Linux noname 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ bash --version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law.
$ cat test.sh
str="{templateUrl: '}" 
regexp="templateUrl:\s*'"

if [[ $str =~ $regexp ]]; then
  echo "yes"
else
  echo "no"
$ bash test.sh
yes 

替换:

regexp="templateUrl:[\s]*'"

与:

regexp="templateUrl:[[:space:]]*'"

根据 man bash=~ 运算符支持 man 3 regex 中定义的 "extended regular expressions"。 man 3 regex 表示它支持 POSIX 标准并将 reader 引用到 man 7 regex。 POSIX 标准支持 [:space:] 作为白色 space 的字符 class。

GNU bash manual 文档支持的字符 class 如下:

Within ‘[’ and ‘]’, character classes can be specified using the syntax [:class:], where class is one of the following classes defined in the POSIX standard:

alnum alpha ascii blank cntrl digit graph lower print
punct space upper word xdigit

我在 GNU bash 文档中唯一提到的 \s 是在提示中的不相关用途,例如 PS1,而不是在正则表达式中。

*

的含义

[[:space:]] 将匹配 恰好一个 白色 space 字符。 [[:space:]]* 将匹配 零个或多个 白色 space 个字符。

spaceblank的区别

POSIX regular expressions 提供两种 class 白色 space:[[:space:]][[:blank:]]

  • [[:blank:]] 表示 space 和制表符。这使得它类似于:[ \t].

  • [[:space:]],除了space和制表符外,还包括换行符、换行符、换页符和垂直制表符。这使得它类似于:[ \t\n\r\f\v].

使用字符 classes 的一个主要优点是它们对于 unicode 字体是安全的。

这应该有效:

#!/bin/bash
str="{templateUrl: '}"
regexp="templateUrl:[[:space:]]*'"

if [[ $str =~ $regexp ]]; then
  echo "yes"
else
  echo "no"
fi

如果要匹配零个或多个空格,需要在 [[:space:]] 之后添加 *