echo `expr "hello" : '\(hi|hello\)'`
echo `expr "hi" : '\(hi|hello\)'`
显然我正在尝试匹配“hello”然后“hi”与regex hello和hi匹配,但两者都不匹配。
我该怎么表达呢?
答案 0 :(得分:3)
或者,简单的球体
case $str in
*hi* | *hello*) echo "pleased to meet you"
esac
答案 1 :(得分:2)
在这个简单的情况下,最好的选择是使用extended globs而不是正则表达式(它会更有效率,让您免于头痛):
string=hello
if [[ $string = @(hi|hello) ]]; then
echo "String matches"
fi
或者(正如你在标题中提到的子串匹配),
string="hello world"
if [[ $string = *@(hi|hello)* ]]; then
echo "String matches"
fi
注意。使用[[
结构,无需启用extglob
:reference manual specifies:
当使用
==
和!=
运算符时,运算符右侧的字符串将被视为一种模式,并根据Pattern Matching中所述的规则进行匹配。
并且模式匹配中的规则描述了扩展的全局。
答案 2 :(得分:1)
expr
的更现代的替代方法是使用Bash regular expressions:
re='hi|hello'
string=hi
[[ $string =~ $re ]] && echo "$string matched"
答案 3 :(得分:1)
|
字符在扩展正则表达式中可用,但expr
仅使用带有:
运算符的基本正则表达式。 [更新:至少在基本正则表达式的POSIX版本中;正如Glenn Jackman所指出的,expr hello '\(hello\|\hi\)'
将与GNU expr
一起工作。您需要将命令重写为对expr
的两次单独调用:
$ expr hello : '\(hello\)' || expr hello : '\(hi\)'
hello
$ expr hi : '\(hello\)' || expr hi : '\(hi\)'
hi
$ expr foo : '\(hello\)' || expr foo : '\(hi\)'
$
这仍然不太理想,因为失败的匹配仍然输出一个空字符串。使用其他答案中提供的替代方案会好得多。特别是,case
语句与POSIX兼容,不依赖于任何bash
扩展名。
更新:虽然正则表达式本身无法使用|
,但您可以在同一个:
的调用中合并两个expr
表达式:
expr hi : '\(hello\)' \| hi : '\(hi\)'
当第一个:
找不到匹配项时,它会尝试第二个匹配项。这可以防止expr
为失败的第一次匹配输出空字符串。