당신의 시도

당신의 시도

사용자에게 URL을 입력하라는 메시지를 표시하고 싶지만 URL에는 A-Z,,,,,,,,,,,,,, 및 만 포함할 수 있습니다.a-z0-9&./=_-:?

예를 들면 다음과 같습니다.

Enter URL:
$ http://youtube.com/watch?v=1234df_AQ-x
That URL is allowed.

Enter URL:
$ https://unix.stackexchange.com/$FAKEurl%

답변1

당신은 가깝습니다.

URL에 허용되는 문자가 하나 이상 포함되어 있는 것이 아니라 허용되지 않는 문자가 하나 이상 포함되어 있는지 확인하고 잘못된 것으로 보고하려고 합니다.

!( 다른 쉘 ^에서도 작동함 bash)을 사용하여 대괄호 표현식의 문자 세트를 무효화할 수 있습니다.

어쨌든, , , 와 같은 범위를 사용하여 문자를 명시적으로 개별적으로 나열하는 것이 옳습니다 a-z. (나열한 26+26+10 문자에만 일치)A-Z0-9C 로케일다른 로케일에서는 수천 개의 다른 문자와 일치하거나 여러 문자로 구성된 정렬된 요소(예: A및 사이에 정렬된 요소)와도 일치할 수 있습니다.ZÉA-Z

case $URL in
  ("" | *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_/\&?:.=-]*)
    echo >&2 "That URL is NOT allowed.";;
  (*)
    echo "That URL is allowed.";;
esac

답변2

당신의 시도

허용된 문자가 하나 이상 포함된 모든 URL이 허용되는 것으로 간주하므로 시도가 예상대로 작동하지 않을 수 있습니다. 공식적으로는 URL을 다음과 결합합니다.

<anything><allowed_character><anything>

일치하는 항목이 없으면 URL을 거부합니다.

이것이 도움이 될 수 있습니다

if ... else ... fi당신이 사용하는 경우

if [[ "${URL}" =~ [^A-Za-z0-9\&./=_:?-] ]]; then
    echo "That URL is NOT allowed."
else
    echo "That URL is allowed."
fi

당신이 원하는 것을 할 수도 있습니다.

여기서는 이항 연산자를 사용하여 에서 =~정규 표현식과 [^A-Za-z0-9\&\./=_-:\?]일치하는 항목을 찾습니다 "${URL}". 이 연산자는 "${URL}"정규식과 일치하기 위해 전체 문자열을 요구하지 않으며 일치하는 하위 문자열이 일치합니다. 이러한 일치는 URL에 허용되지 않는 문자에 대해 찾을 수 있습니다. "not"은 ^문자 세트 정의의 선행 캐럿( )에서 나옵니다. !조건식에는 더 이상 부정이 없습니다 .

금지된 문자가 포함된 경우 "${URL}"정규식이 일치하고 복합 명령이 [[...]]true(0 종료 상태)로 평가됩니다.

답변3

현재 논리가 잘못되었습니다. 입력 URL의 모든 문자가 허용된 문자 집합 외부에 존재하는 경우에만 true를 반환합니다.

다음과 같은 것을 시도해보세요

if [[ "${URL}"  = *[!A-Za-z0-9\&./=_:?-]* ]]
then
  echo "That URL is NOT allowed."
else
  echo "That URL is allowed"
fi

문자 범위 부정(!)으로 인해 이 검사는 입력 URL에 허용된 문자 집합을 벗어난 문자가 하나 이상 포함된 경우 true를 반환하도록 설계되었습니다.

답변4

컴팩트한 솔루션

컴팩트 솔루션을 선호하는 경우 다음 솔루션을 사용할 수 있습니다.

[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No || echo Yes

설명하다

${<variable>//<pattern>}이 솔루션은 보다 일반적인 형식의 특수한 경우인 형식의 인수 확장을 사용합니다.

${<variable>//<pattern>/<replace>}

쉘은 이를 값으로 확장 <variable>하고 그 안에 있는 모든 항목을 <pattern>대체합니다 <replace>. 우리의 경우에는 <replace>비어 있으므로 후행 슬래시를 생략할 수도 있습니다 <pattern>.

결과적으로 "${URL//[A-Za-z0-9\&.\/=_:?-]}"URL은 허용된 모든 문자가 제거된 상태로 확장됩니다. 잔여물이 없는 경우, 즉 URL이 [ ... ]실제로 허용되는 경우 [ ]false(종료 상태 0)가 생성됩니다. 남아 있는 문자가 있는 경우 해당 문자는 억제되고 비어 있지 않은 문자열 인 [ ... ]형식을 가지며 결과는 true(종료 상태 1)입니다.[ <nes> ]<nes>

&&전체 명령은 제어 연산자 (and) 및 (or) 로 구분된 세 가지 명령 목록으로 ||, 왼쪽 연관되어 있습니다. 따라서 하위리스트는

[ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ] && echo No

먼저 평가를 받으세요. 여기서 &&두 번째 피연산자는 첫 번째 피연산자가 true(0 종료 상태)로 평가되는 경우에만 평가됩니다. 이는 URL에 금지된 문자가 포함된 경우 발생합니다. 따라서 echo이 경우 정답 "No"가 제공되고 이 하위 목록의 종료 상태는 다음 echo명령에서 나옵니다: 0(true).

반대로 URL이 허용되면 하위 목록의 종료 상태는 [ ... ]1(false)에서 옵니다.

이제 목록의 나머지 부분을 만듭니다.

<sub-list> || echo Yes

||이 연산자는 첫 번째 피연산자가 false(종료 상태가 0과 다름)인 경우에만 마지막 명령을 실행합니다. 따라서 거짓인 경우에만 <sub-list>, 즉 허용된 URL의 경우 "예"를 얻게 됩니다.

만약 구조

물론 구조 내에서 위 명령을 사용할 [ ... ]수도 있습니다 . if대부분의 경우 이렇게 하면 더 읽기 쉬운 코드가 생성됩니다.

if [ "${URL//[A-Za-z0-9\&.\/=_:?-]}" ]; then
    echo "That URL is NOT allowed."
else
    echo "That URL is allowed."
fi

관련 정보