Bash Regex - 文字列はドットで始まり、終わらないでください。

Bash Regex - 文字列はドットで始まり、終わらないでください。

ユーザーの文字列入力を受け入れるスクリプトがあります。文字列入力に正確に2つの点があることを確認したいと思います。相関関係は単にポイントに関するものです。文字列はドットで始まり終わらないでください。連続した点があってはなりません。

これが私が使用するパターンです:

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

これが私が探している文字列です:

abc.def.xyz

ただし、上記のパターンで点が前後にある場合は、文字列が選択されます。これは望ましくありません。文字列には2つの点しか含まれていません。

不要:

.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 dotsを試してみましたが、成功しませんでした。

ベストアンサー1

ユーザーが文字列を入力する方法は明らかではありませんが、改行が含まれている場合は一度に1行だけ処理するため(拡張子を使用しない限り)grepフィルタリングできません。また、正規表現はバックスラッシュおよびを除く文字と一致し、多くの正規表現実装の正規表現演算子(または)は、ロケールで有効な文字を形成しないバイトと一致しません。--nullgrep[^\.]..[...]

ここで2つの点があることを確認するには、$string開始または終了ではなく、互いに隣接していないことを確認するには、次の基準を使用できますsh

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

または、ksh globを使用して次の手順を実行して、bashシェルでksh globのサブセットを使用できます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

おすすめ記事