我试图匹配列表中单词的存在,然后再次添加该单词(以避免重复)。我正在使用bash 4.2.24并尝试以下内容:
[[ $foo =~ \bmyword\b ]]
也
[[ $foo =~ \<myword\> ]]
然而,似乎都不起作用。它们在bash docs示例中提到:http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html。
我认为我做错了什么,但我不确定是什么。
答案 0 :(得分:26)
是的,支持所有列出的正则表达式扩展,但在使用之前将模式放在变量中会更好。试试这个:
re=\\bmyword\\b
[[ $foo =~ $re ]]
挖掘我发现this question,其答案似乎解释了当正则表达式以内联方式编写时,行为会发生变化的原因。
编者注::链接的问题不解释OP的问题;它只是解释了如何从Bash版本3.2正则表达式(或至少是特殊的正则表达式字符符号)开始必须默认不带引号才能被视为 - 这正是OP所尝试的。
但是,此答案中的解决方法有效。
您可能需要重写测试以便为正则表达式使用临时变量,或者使用3.1兼容模式:
shopt -s compat31
答案 1 :(得分:5)
接受的答案集中在使用辅助变量来处理Bash的[[ ... ]]
表达式中正则表达式的语法奇怪性。非常好的信息。
然而,真正的答案是:
\b
\<
和\>
无法在OS X 10.11.5(El Capitan)上使用bash版本4.3.42(1)-release(x86_64-apple-darwin15。 0.0)。
相反,请使用[[:<:]]
和[[:>:]]
。
答案 2 :(得分:4)
不完全&#34; \ b&#34;,但对我来说比其他建议更具可读性(和便携性):
[[ $foo =~ (^| )myword($| ) ]]
答案 3 :(得分:2)
与您的问题相切,但如果您可以在脚本中使用grep -E
(或egrep
,其有效但过时的别名):
if grep -q -E "\b${myword}\b" <<<"$foo"; then
我最后使用bash的=~
。
请注意,虽然正则表达式构造\<
,\>
和\b
不符合POSIX,但grep -E
的BSD(macOS)和GNU(Linux)实现支持它们,这使得这种方法在实践中广泛使用。
小警告(手头不是问题):如果不使用=~
,您将失去通过${BASH_REMATCH[@]}
稍后检查捕获子表达式(捕获组)的能力。
答案 4 :(得分:2)
我使用以下内容来匹配旧系统上的字边界。关键是用a :: p -> (a, b)
包含空格,因为$foo
将不匹配列表开头或结尾的单词。
[^[:alpha:]]
根据[[ " $foo " =~ [^[:alpha:]]myword[^[:alpha:]] ]]
的预期内容根据需要调整字符类,否则这可能不是一个好的解决方案。
答案 5 :(得分:1)
这对我有用
bar='\<myword\>'
[[ $foo =~ $bar ]]
答案 6 :(得分:1)
你可以使用grep,它比bash的正则表达式更便携,如下所示:
if echo $foo | grep -q '\<myword\>'; then
echo "MATCH";
else
echo "NO MATCH";
fi