bash에서 복잡한 정규 표현식을 작동시키는 방법

bash에서 복잡한 정규 표현식을 작동시키는 방법

아이디어는 URL의 입력 패턴에 대한 기본 검사를 수행하는 것입니다.

$ ns='abc.def.com'
$ reg_expr="\N*\.(\D{2}|\D{3})$"
$ echo $reg_expr
\N*\.(\D{2}|\D{3})$
$ [[ $ns =~ "$reg_expr" ]] && echo "ok" || echo "no"
no

그러나 정규식은 항상 실패합니다. 동일한 패턴에 대한 온라인 정규식 검사가 제대로 작동합니다.

https://regex101.com/r/vXxv1w/1

왜 이런 일이 발생합니까?

답변1

저것

\N*\.(\D{2}|\D{3})$

Perl 정규 표현식입니다. bash의 [[ =~ ]]연산자는 Perl 정규식이 아닌 POSIX 확장 정규식을 사용합니다.

Perl 스타일 정규식을 사용하려면 zsh 및 해당 rematchpcre옵션을 사용하십시오.

set -o rematchpcre
[[ $ns =~ '\N*\.(\D{2}|\D{3})$' ]]

이제 이 정규식은 별로 의미가 없습니다.

  • \N줄 바꿈을 제외한 모든 문자와 일치하도록 설계되었지만 플래그를 설정하지 않는 한 s(예: (?s)) 을 사용하여 .줄 바꿈은 일치하지 않으므로 \N로 바꿀 수 있습니다 ..
  • <anything>*일치하기 때문에 정규식의 시작이나 끝 부분 에 있는 것은 의미가 없습니다.0또는 more <anything>이므로 아무것도 일치하지 않습니다. [[ $ns =~ '\.(\D{2}|\D{3})$' ]]기능적으로 동일합니다.
  • \D10진수(예: 0123456789 또는 0123456789٠١٢٣٤٥٦٧٨٩0123356789ot German)를 제외한 모든 문자와 일치합니다. ८ ८ ८ ০১২৩৪৫৬৭৮৯੦੧੨੩੪੫੬੭੮੯૦૧૨૩૪૫૬૭૮૯ ९ ୭ ୭ ൯ ෦෧෨෩෪෫෬෭෮෯ ๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨ ๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨ ༩၀၁၂၃၄၅၆၇၈၉႐႑႒႓႔႕႖႗႘႙០១២៣៤៥៦៧៨៩᠐᠑᠒᠓᠔ ᠕᠖᠗᠘᠙ ᠕᠖᠗᠘᠙ ᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏ ᧑᧒᧓᧔᧕᧖᧗᧘᧙᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉᪐᪑᪒᪓᪔᪕ ᪖᪗᪘᪙᭐ ᭑᭒᭓᭔᭕᭖᭗᭘᭙᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉᱐᱑᱒᱓᱔᱕ ᱖᱗᱘᱙꘠꘡ ᱖᱗᱘᱙꘠꘡ KR 0123456789

답변2

의 매뉴얼 페이지에는 테스트에 유효한 연산자를 bash설명하는 여러 단락이 있습니다 . [[ expression ]]정규식 일치에 관한 기사에서는 다음과 같이 말합니다.

== 및 !=와 우선순위가 동일한 추가 이항 연산자 =~를 사용할 수도 있습니다. 사용 시 연산자 오른쪽의 문자열은 POSIX 확장 정규식으로 처리되어 그에 따라 일치됩니다.

(몇 문장 건너뛰기)

패턴의 일부가 인용되면 인용된 부분이 문자 그대로 일치됩니다. 이는 인용된 부분의 모든 문자가 특별한 패턴 일치 의미 없이 자체적으로 일치함을 의미합니다. 패턴이 쉘 변수에 저장된 경우 인용 변수 확장은 전체 패턴을 문자 그대로 일치시킵니다.

요약하면, 내부적으로 [[ expression ]]정규식 주위에 따옴표를 넣지 말고 정규식이 포함된 변수 주위에도 따옴표를 넣지 마십시오. =~정규식을 인용하면 비교 연산자로 지정했더라도 비교가 순수 문자열 일치로 변경됩니다 ==.

어떤 정규식 구문이 지원되는지 알아보려면 매뉴얼 페이지의 참조를 따르는 것이 좋습니다. [[:digit:]]and [^[:digit:]]대신 \dand 를 사용할 수도 있습니다 \D. (틀릴 수도 있으니 직접 확인해보세요)

관련 정보