ユーザーの文字列入力を受け入れるスクリプトがあります。文字列入力に正確に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
フィルタリングできません。また、正規表現はバックスラッシュおよびを除く文字と一致し、多くの正規表現実装の正規表現演算子(または)は、ロケールで有効な文字を形成しないバイトと一致しません。--null
grep
[^\.]
.
.
[...]
ここで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