【发布时间】:2017-08-02 14:09:54
【问题描述】:
我希望下面的代码回显“是”,但事实并非如此。由于某种原因,它与单引号不匹配。为什么?
str="{templateUrl: '}"
regexp="templateUrl:[\s]*'"
if [[ $str =~ $regexp ]]; then
echo "yes"
else
echo "no"
fi
【问题讨论】:
我希望下面的代码回显“是”,但事实并非如此。由于某种原因,它与单引号不匹配。为什么?
str="{templateUrl: '}"
regexp="templateUrl:[\s]*'"
if [[ $str =~ $regexp ]]; then
echo "yes"
else
echo "no"
fi
【问题讨论】:
替换:
regexp="templateUrl:[\s]*'"
与:
regexp="templateUrl:[[:space:]]*'"
根据man bash,=~ 运算符支持man 3 regex 中定义的“扩展正则表达式”。 man 3 regex 表示它支持 POSIX 标准并将读者推荐给 man 7 regex。 POSIX 标准支持[:space:] 作为空格的字符类。
GNU bash manual 记录了支持的字符类,如下所示:
在‘[’和‘]’中,可以使用 语法 [:class:],其中 class 是定义的以下类之一 在 POSIX 标准中:
alnum alpha ascii 空白 cntrl 数字图下方打印
punct 空格高位字xdigit
我在 GNU bash 文档中发现 \s 的唯一提及是在提示符中的不相关使用,例如 PS1,而不是在正则表达式中。
*的含义
[[:space:]] 将匹配一个空白字符。 [[:space:]]* 将匹配 零个或多个 个空格字符。
space和blank的区别
POSIX regular expressions 提供两类空白:[[:space:]] 和 [[:blank:]]:
[[:blank:]] 表示空格和制表符。这使它类似于:[ \t]。
[[:space:]] 除了空格和制表符之外,还包括换行符、换行符、换页符和垂直制表符。这使它类似于:[ \t\n\r\f\v]。
使用字符类的一个关键优势是它们对于 unicode 字体是安全的。
【讨论】:
[:space:]表示所有空格,包括回车和换行;而[:blank:] 表示“水平”空白(空格和制表符) -- regular-expressions.info/posixbrackets.html
regexp="templateUrl:\ *'"
regexp="templateUrl: *'" 也可以。当然,无论哪种情况,这都会将正则表达式限制为匹配实际的 ASCII 空白。 [[:blank:]] 或 [[:space:]] 可能识别的其他空白字符不匹配。
去掉正则表达式中的方括号:
regexp="templateUrl:\s*'"
存在方括号时,内部的\s 被逐字解释为匹配\ 或s 字符,但您的意图显然是匹配\s 是简写的空白字符类(因此不需要方括号)。
$ 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*'" 仍然会回显“不”。
yes。我在 Linux Mint 17 机器上运行。我会更新答案以反映这一点。
这应该可行:
#!/bin/bash
str="{templateUrl: '}"
regexp="templateUrl:[[:space:]]*'"
if [[ $str =~ $regexp ]]; then
echo "yes"
else
echo "no"
fi
如果要匹配零个或多个空格,则需要在 [[:space:]] 之后添加 *。
【讨论】:
* 似乎是需要的。
GNU bash, version 4.2.25 中不需要它。
*。如果您想完全匹配一个空格,则不需要。