Bash
bash 正則表達式提取鍵 = 值
我有一個這種形式的複雜字元串:
inp="key1 = what' ever the value key2 = the value Nb.2 key3= \"last value\""
我需要獲取與其第一個值關聯的第一個鍵。我想使用 bash 正則表達式來提取鍵、值以及字元串中剩餘的內容:
rkeyval="[[:space:]]*([_[:alnum:]]*?)[[:space:]]*=[[:space:]]*((.*?)[[:space:]]+([_[:alnum:]]+?[[:space:]]*=[[:space:]]*.*))" if [[ $inp =~ $rkeyval ]]; then key=${BASH_REMATCH[1]} val=${BASH_REMATCH[3]} left=${BASH_REMATCH[4]} for i in $(seq 0 $(( ${#BASH_REMATCH[*]}-1 ))); do echo -e "$i: \"${BASH_REMATCH[$i]}\""; done; else echo "no match" fi
這不起作用。在我的帶有 Bash 4.4 的 Mac 上,沒有匹配項:
no match
在我的 Red Hat Linux 上,我得到以下輸出:
0: "key1 = what' ever the value key2 = the value Nb.2 key3= "last value"" 1: "key1" 2: "what' ever the value key2 = the value Nb.2 key3= "last value"" 3: "what' ever the value key2 = the value Nb.2 " 4: "key3= "last value""
我期望以下輸出:
0: "key1 = what' ever the value key2 = the value Nb.2 key3= "last value"" 1: "key1" 2: "what' ever the value key2 = the value Nb.2 key3= "last value"" 3: "what' ever the value" 4: "key3= "last value""
換句話說,鍵是第二個匹配組,值是第三個。
此表達式適用於線上PHP 正則表達式測試器。
我希望它可以在任何具有 Bash 更新版本的 Unix 機器上工作。
我不知道為什麼這不起作用,以及為什麼結果因平台而異,即使我的正則表達式尊重 Posix 約定(或者這樣做?)。我在這裡做錯了什麼?
星號已經是一個可選計數(因為它可能是零個字元)。無需添加
?
。那麼,如果每個括號都擷取一個鍵或一個值,可以嗎?:
s='[[:space:]]*' # spaces n='[_[:alnum:]]+' # a valid name (limited by spaces) e="${s}=${s}" # an equal sign (=). rkeyval="${s}(${n})${e}([^=]*) (${n})${e}([^=]*) (${n})${e}(.*)" # 1^^^^^ 2^^^^^^ 3^^^^^ 4^^^^^^ 5^^^^^ 6^^^ echo "$rkeyval"
這將像這樣擷取:
if [[ $inp =~ $rkeyval ]]; then i=0 while ((i<${#BASH_REMATCH[@]})); do printf '%s: "%s"\n' "$((i))" "${BASH_REMATCH[i++]}"; done else echo "no match" fi
印刷:
0: "key1 = what' ever the value key2 = the value Nb.2 key3= "last value"" 1: "key1" 2: "what' ever the value" 3: "key2" 4: "the value Nb.2 " 5: "key3" 6: ""last value""
您想要的值(如果我正確理解您的程式碼)可以近似為(編輯以獲得完美匹配):
key="${BASH_REMATCH[1]}" val="${BASH_REMATCH[@]:2:3}" left="${BASH_REMATCH[@]:5:2}"
POSIX 沒有
*?
為 Bash 使用的ERE定義,而是指定:多個相鄰重複符號(“+”、“*”、“?”和間隔)的行為會產生未定義的結果。
Bash使用系統
regcomp
/regexec
進行正則表達式匹配。蘋果的 libc 大概沒有實現你想要的行為*?
。沒有標準的方法可以從貪婪中恢復非貪婪匹配語義,儘管在這種情況下,至少其中一些是不必要的(
[_[:alnum:]]*?
例如,第一個)。否則,您需要轉換錶達式以匹配其他內容或提前(可能之後)改變數據以獲得效果。