![당신의 시도](https://linux55.com/image/147534/%EB%8B%B9%EC%8B%A0%EC%9D%98%20%EC%8B%9C%EB%8F%84.png)
사용자에게 URL을 입력하라는 메시지를 표시하고 싶지만 URL에는 A-Z
,,,,,,,,,,,,,, 및 만 포함할 수 있습니다.a-z
0-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-Z
0-9
C 로케일다른 로케일에서는 수천 개의 다른 문자와 일치하거나 여러 문자로 구성된 정렬된 요소(예: 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