ユーザーの文字列入力を受け入れるスクリプトがあります。文字列入力に正確に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
答え2
私はあなたがこの正規表現を探していると思います。^[^.]\+\.[^.]\+\.[^.]\+$
この例では、以下を使用しますgrep
。
括弧内の文字は文字通り処理されるので(除く-
)エスケープポイントは必要ありません。
$ echo ".a.b.c." | grep "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo ".a.b.c" | grep "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a.b.c." | grep "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a..c" | grep "^[^.]\+\.[^.]\+\.[^.]\+$"
$ echo "a.b.c" | grep "^[^.]\+\.[^.]\+\.[^.]\+$"
a.b.c
正規表現は言う
- 文字列は、1つ以上の非ドット文字で始まり、その後にドット、
^[^.]\+\.
1つ以上のドット以外の文字[^.]\+\.
、次に1つ以上のドット以外の文字が行の[^.]\+$
終わりに来る必要があります。
答え3
awkでは、次のことができます。
$ awk ' $0"." ~ /^([^.]+\.){3}$/ ' file
a.b.c
abc.def.xyz
1つ追加指す最後にパターンを繰り返し、3回だけフォローnot-dot
しますdot
。ㅏ。-雨。-氏。またはアルファベット。-定義。-XYZ。
または正規表現の用語で言うと、次のようになります。([^.]\.){3}
正規表現が行全体と一致できる場合にのみ許可されます。
答え4
Bashでこれを行うには、次の1つの方法に従ってください。
IFS="." read -ra words <<<"$input"
if ((${#words[@]} == 3)) && [[ $input != .* && $input != *. ]]; then
echo "valid input"
fi
これは実際には単語配列の値を使用します。
IFS="." read -ra words <<<"$input"
# 3 dot-separated fields, and the first and last cannot be empty
if ((${#words[@]} == 3)) && [[ -n ${words[0]} && -n ${words[2]} ]]; then
echo "valid input"
fi