Bash

Bash Regex - 字元串不應以點開頭和結尾

  • October 6, 2021

我有一個從使用者那裡獲取字元串輸入的腳本。我正在檢查字元串輸入是否應該正好有 2 個點。相關性僅與點有關。字元串不應以點開頭和結尾。不應有連續的點。

這是我正在使用的模式:

^[^\.]*\.[^\.]*\.[^\.]*$

這是我正在尋找的字元串

abc.def.xyz

但在上面的模式中,如果點在前面或末尾,那麼該字元串會被選中——我不想要。字元串中應該只有兩個點。

不想要:

.abc.xyz # no dot at the start   
abc.xyz. # no dot at the end   
abc.def.ced.xyz # only two dots not more than that

我曾嘗試(?!\.)在開始時使用 for 點,但它沒有用。

您並不是說字元串是如何從使用者輸入的,但請注意,如果它可能包含換行符,則不能像一次只在一行上那樣grep使用它們來過濾它們(除非您使用--null副檔名) 。grep另請注意,[^\.]正則表達式匹配反斜杠以外的字元,.並且許多正則表達式實現中的.正則表達式運算符(或[...])不會匹配在區域設置中不形成有效字元的字節。

在這裡,要檢查$string包含 2 個且僅 2 個點,但不在開頭或結尾且不相鄰,您可以使用標準sh

case $string in
 (*.*.*.* | .* | *. | *..* ) echo not OK;;
 (*.*.*) echo OK;;
 (*) echo not OK;;
esac

或者使用 ksh glob,其中的一個子集可以通過執行以下操作在 bash shell 中提供shopt -s extglob

case $string in
 ( +([!.]).+([!.]).+([!.]) ) echo OK;;
 (*) echo not OK;;
esac

bash``=~還可以在其ksh 樣式構造中使用運算符進行擴展正則表達式匹配[[...]],但同樣,您需要將語言環境修復為 C:

regex_match_in_C_locale() {
 local LC_ALL=C
 [[ $1 =~ $2 ]]
}

if regex_match_in_C_locale "$string" '^[^.]+\.[^.]+\.[^.]+$'; then
 echo OK
else
 echo not OK
fi

POSIXly,您可以使用該expr實用程序進行基本的正則表達式匹配:

if
 LC_ALL=C expr "x$string" : 'x[^.]\{1,\}\.[^.]\{1,\}\.[^.]\{1,\}$' > /dev/null
then
 echo OK
else
 echo not OK
fi

awk或與實用程序匹配的擴展正則表達式:

regex_match_in_C_locale() {
 LC_ALL=C awk -- 'BEGIN {exit(ARGV[1] !~ ARGV[2])}' "$@"
}
if regex_match_in_C_locale "$string" '^[^.]+\.[^.]+\.[^.]+$'; then
 echo OK
else
 echo not OK
fi

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