사용자의 문자열 입력을 받아들이는 스크립트가 있습니다. 문자열 입력에 정확히 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 dots을 사용해 보았 으나 성공하지 못했습니다.
답변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
정규 표현식은 말한다
- 문자열은 하나 이상의 점이 아닌 문자로 시작하고 그 뒤에 점
^[^.]\+\.
, 하나 이상의 점이 아닌 문자[^.]\+\.
, 그 다음 하나 이상의 점이 아닌 문자가[^.]\+$
줄 끝까지 와야 합니다.
답변3
awk에서는 다음과 같이 할 수 있습니다:
$ awk ' $0"." ~ /^([^.]+\.){3}$/ ' file
a.b.c
abc.def.xyz
하나 추가가리키다마지막으로 패턴을 반복하게 만들고, 3번만 not-dot
따라합니다 dot
.ㅏ.--비.--씨.또는알파벳.--정의.--XYZ.
또는 정규식 용어로 말하면 다음과 같습니다.([^.]\.){3}
정규 표현식이 전체 줄과 일치할 수 있는 경우에만 허용됩니다.
답변4
Bash에서 이 작업을 수행하려면 다음 한 가지 방법을 따르세요.
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