Bash

bash 條件表達式和反斜杠轉義

  • October 29, 2020

我真的很難理解這種行為:

stackExchange@test:~$ if [[ "two words" =~ \bwords ]]; then echo hi; fi; #(I'd expect this one worked)
stackExchange@test:~$ if [[ "two words" =~ \\bwords ]]; then echo hi; fi; #(or at least this one...)
stackExchange@test:~$ if [[ "two words" =~ \\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ if [[ "two words" =~ \\\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ put_in_a_variable=\\bwords
stackExchange@test:~$ if [[ "two words" =~ $put_in_a_variable ]]; then echo hi; fi;
hi
stackExchange@test:~$

我知道我的變數包含\bword並且這在條件表達式的模式部分得到了擴展,但我真的不明白為什麼使用內聯 shell 轉義似乎不可能實現相同的行為。

我不想做類似的事情if [[ "two words" =~ $(echo \\bwords) ]]; then echo hi; fi;;太詭異了……

謝謝,

弗朗西斯科

正則表達式部分中的反斜杠的效果[[ str =~ rex ]]引用以下字元(就像將其放在單引號中一樣),這將指示 bash 對其進行文字匹配(1)。因為b不是特殊的,所以\b會變成 just b, but '\', "\\"or\\會變成\\為了匹配文字反斜杠:

[[ abwords =~ \bwords ]] && echo "<$BASH_REMATCH>"
<bwords>
[[ 'a\bwords' =~ \\bwords ]] && echo "<$BASH_REMATCH>"
<\bwords>
# conversely, '|' is just like \|
[[ 'a|words' =~ a'|'words ]] && echo "<$BASH_REMATCH>"
<a|words>

您將正則表達式放入變數的想法很好。另一種方法是使用包裝函式:

rematch() [[ $1 =~ $2 ]]

if rematch 'two words' '\bwords\b'; then
 echo "<$BASH_REMATCH>"
fi
<words>

(1):如其手冊中所述:

可以引用模式的任何部分以強制將引用的部分匹配為字元串

請注意,在 shell 中,被引用的字元實際上是被特別標記的,因此解析器的任何後續處理都可以基於字元串的一部分是被引用還是未被引用來決定。

引用自:https://unix.stackexchange.com/questions/617083