Bash Regex - 문자열은 점으로 시작하고 끝나서는 안 됩니다.

Bash Regex - 문자열은 점으로 시작하고 끝나서는 안 됩니다.

사용자의 문자열 입력을 받아들이는 스크립트가 있습니다. 문자열 입력에 정확히 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필터링 할 수 없다는 점에 유의하세요. 또한 정규식은 백슬래시 및 를 제외한 문자와 일치하며 많은 정규식 구현의 정규식 연산자(또는 ) 는 로케일에서 유효한 문자를 형성하지 않는 바이트와 일치하지 않습니다.--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

답변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

관련 정보