큰따옴표와 작은따옴표가 포함된 정규식을 변수에 올바르게 압축하고 Bash에서 평가하려면 어떻게 해야 합니까?

큰따옴표와 작은따옴표가 포함된 정규식을 변수에 올바르게 압축하고 Bash에서 평가하려면 어떻게 해야 합니까?

이것stackoverflow 질문은 RFC5322 호환 이메일 형식 일치에 대해 다음 정규식을 제공합니다.

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

정규식에는 일치해야 하는 작은따옴표와 큰따옴표가 포함되어 있습니다.

이것을 변수에 저장한 다음 평가하는 정확하고 이식 가능한 Bash 방법은 무엇입니까?

내 접근 방식은 작은 따옴표를 사용한 다음 정규식의 각 작은 따옴표 앞에 작은 따옴표 부분을 끝내고 이스케이프된 작은 따옴표를 추가한 다음 나머지 작은 따옴표를 계속 사용하는 것이었습니다. 그 결과는 다음과 같습니다(원래 정규식에 유의하세요) '. 수식의 모든 내용을 다음으로 바꾸고 전체 정규식의 시작과 끝에 '\''하나를 추가합니다 .'

regex='(?:[a-z0-9!#$%&'\''*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'\''*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])'

그런 다음 입력 echo $regex(및 echo "$regex$")은 원래 링크에 정의된 대로 정확하게 정규식 문자열을 출력합니다. 그런 다음 평가해 보세요.

if [[ "$email" =~ $regex ]] ; then
    echo "This is an RFC5322 compliant e-mail address"
else
    echo "This is NOT an RFC5322 compliant e-mail address"
fi

그러나 일반 이메일 주소만으로는 테스트가 실패합니다. (사용하는 경우에도 실패합니다.)email="[email protected]"if [[ "$email" =~ "$regex" ]] ; then

문제는 무엇이며 bash에서 이를 수행하는 가장 좋고 깨끗한 방법은 무엇입니까? (누군가 bash를 사용하지 말라고 한다면 불행히도 이것은 RFC5322 준수와 마찬가지로 전제 조건입니다)

답변1

perl이것이 in 을 사용하여 수행하는 방법입니다 bash.

  • Perl의 환경 트레이에 정규식을 배치하십시오.
  • 이메일 주소를 Perl의 표준 입력으로 파이프합니다.
  • 그런 다음 Perl에서 일치시키고 반대 상태로 종료하려고 시도하십시오. 왜냐하면 bash와 Perl은 상호 보완적인 성공 감각을 가지고 있기 때문입니다.
  • 휴식은 당신의 사업입니다.
printf '%s\n' "$email" \
| _regex_="$regex"     \
     perl -0777 -ne 'chop;exit !/$ENV{_regex_}/'

if [[ $? == 0 ]] ; then
    echo "This is an RFC5322 compliant e-mail address"
else
    echo "This is NOT an RFC5322 compliant e-mail address"
fi

관련 정보