정규식은 기본적으로 문자열을 처리하는 데 사용되며, 문자열을 일치시키고 추출하고 바꾸는 데 정규식을 사용하면 매우 편리합니다.
하지만 정규식을 익히는 것은 여전히 다소 어려운 부분이 있습니다. 탐욕적 매칭, 비탐욕적 매칭, 하위 그룹 캡처, 비캡처 하위 그룹 등의 개념은 초보자뿐만 아니라 몇 년 동안 일한 많은 사람들에게도 이해하기 어려울 수 있습니다.
그렇다면 정규식을 배우는 가장 좋은 방법은 무엇일까요? 정규식을 빨리 익히는 방법은 무엇입니까?
제가 생각하기에 매우 좋다고 생각되는 규칙적인 규칙을 학습하는 방법을 추천합니다: AST를 통한 학습 .
정규식의 일치 원리는 패턴 문자열을 AST로 구문 분석한 다음 이 AST를 사용하여 대상 문자열을 일치시키는 것입니다.
패턴 문자열의 다양한 정보는 구문 분석 후 AST에 저장됩니다. AST는 이름에서 알 수 있듯이 문법적 구조에 따라 구성된 트리입니다. AST의 구조를 보면 정규 표현식이 지원하는 구문을 쉽게 알 수 있습니다.
정규식의 AST를 보는 방법은 무엇입니까?
astexplorer.net 웹사이트를 통해 시각적으로 볼 수 있습니다.
구문 분석 언어를 RegExp로 전환하면 정규식의 AST를 시각화할 수 있습니다.
앞서 언급했듯이 AST는 문법에 따라 구성된 트리이므로 그 구조에서 다양한 문법을 쉽게 분류할 수 있습니다.
그런 다음 AST 관점에서 다양한 구문을 배워 보겠습니다.
간단한 것부터 시작해 보겠습니다. /abc/ 이러한 정규식은 'abc' 문자열과 일치할 수 있으며 해당 AST는 다음과 같습니다.
3 Char 값은 각각 a, b, c 이며, 종류는 간단합니다. 후속 일치는 AST를 순회하여 이 세 문자를 각각 일치시키는 것입니다.
exec API를 사용하여 테스트했습니다.
0번째 요소는 일치하는 문자열이고 index는 일치하는 문자열의 시작 인덱스입니다. 입력은 입력 문자열입니다.
특수 문자를 다시 시도해 보겠습니다.
/ddd/는 세 개의 숫자가 일치한다는 의미입니다. d는 정규 표현식에서 지원하는 특별한 의미를 갖는 메타 문자(메타 문자)입니다.
또한 AST를 통해 Char이기도 하지만 유형이 실제로는 메타임을 확인할 수 있습니다.
d 메타 문자를 사용하면 어떤 숫자든 일치할 수 있습니다.
어떤 것이 메타문자인지, 어떤 것이 단순문자인지는 AST를 통해 한눈에 알 수 있습니다.
Regular는 []를 통해 문자 집합을 지정하는 것을 지원합니다. 이는 모든 문자와 일치할 수 있음을 의미합니다.
또한 AST에서 CharacterClass 레이어로 래핑되어 있음을 볼 수 있습니다. 이는 문자 클래스를 의미합니다. 즉, 포함된 모든 문자와 일치할 수 있습니다.
실제로 테스트 중인 사례는 다음과 같습니다.
정규 표현식은 {from,to} 형식을 사용하여 특정 문자가 반복되는 횟수를 지정하도록 지원합니다.
예를 들어 /b{1,3}/는 문자 b가 1~3회 반복됨을 의미합니다. , /[abc ]{1,3}/는 이 a/b/c 문자 클래스가 1~3회 반복됨을 의미합니다.
AST에서 볼 수 있듯이 이 구문을 반복이라고 합니다.
여기에는 수량자를 나타내는 수량자 속성이 있습니다. 여기서 유형은 1에서 3까지의 범위입니다.
정규식은 1~무수한 횟수를 나타내는 +, 0~무수한 횟수를 나타내는 *, 0 또는 1회를 나타내는 ?와 같은 일부 수량자의 약어도 지원합니다.
이는 다양한 유형의 수량자입니다.
어떤 수련생은 여기서 탐욕스러운 속성이 무엇을 의미하는지 묻습니다.
탐욕은 탐욕을 의미합니다. 이 속성은 이 반복이 탐욕스러운 일치인지 비탐욕적인 일치인지를 나타냅니다.
수량자 뒤에 ?를 추가하면 탐욕이 거짓이 되어 비탐욕 일치로 전환됩니다.
그렇다면 탐욕스러운 것과 탐욕스럽지 않은 것은 무엇을 의미하는가?
예를 살펴보겠습니다.
기본 반복 매칭은 탐욕적이며 조건이 충족되는 한 계속해서 매칭되므로 여기에서 acbac를 매칭할 수 있습니다.
수량자가 non-greedy로 전환된 후에 ?를 추가하면 첫 번째만 일치됩니다.
이것이 탐욕적 일치와 비탐욕적 일치입니다. AST를 통해 우리는 반복 문법에 대한 탐욕적 일치를 확실히 알 수 있습니다.
정규식은 일치하는 문자열의 일부를 하위 그룹에 넣고 ()를 통해 반환하는 것을 지원합니다.
AST를 살펴보세요.
해당 AST를 그룹이라고 합니다.
그리고 여기에는 기본값이 true인 캡처 속성이 있음을 알 수 있습니다.
이것은 무엇을 의미합니까?
이는 하위 그룹 캡처의 구문입니다.
하위 그룹을 캡처하지 않으려면 다음과 같이 작성하면 됩니다(?:aaa)
보세요, 캡처가 거짓이 되었습니다.
캡처와 비캡처의 차이점은 무엇인가요?
시도해 봅시다:
아, Group의 캡처 속성이 추출 여부를 나타내는 것으로 밝혀졌습니다.
AST에서 캡처가 하위 그룹에 대한 것임을 알 수 있습니다. 이는 하위 그룹의 콘텐츠가 추출된다는 의미입니다. ?:를 통해 비캡처로 전환할 수 있으며 하위 그룹의 콘텐츠는 추출되지 않습니다.
우리는 정규 구문을 이해하기 위해 AST를 사용하는 것에 이미 익숙하지만 좀 더 어려운 것을 살펴보겠습니다.
정규식은 (?=xxx) 구문을 통해 예측 어설션 표현을 지원합니다. 특정 문자를 판단하는 데 사용됩니다. 문자열 앞에 특정 문자열이 있는지 여부입니다.
AST를 통해 이 구문을 Assertion이라고 하며 유형은 앞을 내다보는 것을 의미하는 Lookahead라는 것을 알 수 있습니다. 이전 의미와만 일치합니다.
이것은 무엇을 의미합니까? 왜 이런 글을 쓰나요? /bbb(ccc)/와 /bbb(?:ccc)/의 차이점은 무엇인가요?
시도해 봅시다:
결과에서 볼 수 있습니다.
/bbb(ccc)/는 ccc의 하위 그룹과 일치하고 기본 하위 그룹이 캡처되므로 이 하위 그룹을 추출합니다.
/bbb(?:ccc)/는 ccc의 하위 그룹과 일치하지만 ?:를 통해 하위 그룹을 캡처하지 않도록 설정했기 때문에 추출되지 않습니다.
/bbb(?=ccc)/ ccc와 일치하는 하위 그룹은 추출되지 않으며, 이는 역시 비캡처임을 나타냅니다. 그것과 ?:의 차이점은 일치 결과에 ccc가 나타나지 않는다는 것입니다.
이것이 예측 어설션의 특성입니다. 예측 어설션은 특정 문자열 앞에 특정 문자열이 있고 해당 하위 그룹이 캡처되지 않으며 어설션된 문자열이 일치 결과에 나타나지 않음을 의미합니다.
해당 문자열이 뒤에 오지 않으면 일치하지 않습니다.
?=를 ?!로 변경하면 AST를 통해 살펴보세요.
미리보기 어설션이 여전히 먼저 주장되지만 true라는 부정적인 속성이 추가로 있습니다.
원래 의미는 앞이 어떤 문자열이라는 뜻이고, 부정 뒤에는 앞이 어떤 문자열이 아니라는 뜻이다.
그러면 일치하는 결과는 정반대입니다.
이제 앞에 있는 특정 문자열이 아닌 경우에만 일치합니다. 이는 부정적인 예견 주장입니다.
선행 주장이 있으면 자연스럽게 후행 주장도 있게 됩니다. 즉, 뒤에 특정 문자열이 따라오는 경우에만 일치합니다.
같은 방식으로 거부할 수도 있습니다.
(?<=aaa)에 해당하는 AST는 생각하기 쉽습니다. 이는 LookBehind 주장입니다.
(?<!aaa)에 해당하는 AST는 부정적인 속성을 추가하는 것입니다.
Look-ahead Assertion과 Look-Behind Assertion은 가장 이해하기 어려운 정규식 구문입니다. AST를 통해 배우면 훨씬 이해하기 쉽습니다 ~
정규식은 문자열을 처리하는 데 매우 편리한 도구이지만 여전히 다소 어렵습니다. 많은 사람들이 탐욕적 일치, 비탐욕적 일치, 하위 그룹 캡처, 비캡처 하위 그룹, 예측 어설션, 뒤돌아보기 어설션 등과 같은 구문에 대해 혼란스러워합니다.
AST를 통해 규칙적인 규칙을 학습하는 것이 좋습니다. AST는 문법 구조에 따라 구성된 객체 트리입니다. AST 노드의 이름과 속성을 통해 다양한 구문을 쉽게 알 수 있습니다.
예를 들어 AST를 통해 다음과 같이 명시했습니다.
반복 구문(Repetition)은 문자 + 한정자 형식입니다. 기본값은 탐욕적 일치(greedy is true)입니다. 이는 일치자가 없음으로 전환된 후 ?를 추가하는 것을 의미합니다. -탐욕스러운 일치. , 한 문자가 일치하면 중지됩니다.
특정 문자열을 추출하기 위해 하위 그룹 구문(Group)을 사용합니다. 기본값은 캡처(캡처가 true)이므로 추출이 필요하다는 의미입니다. 일치만 하고 추출하지 않는 (?:xxx)를 통해 비캡처로 전환할 수 있습니다. .
Assertion 구문(Assertion)은 Lookahead Assertion과 Lookbehind Assertion으로 구분됩니다. 부정(부정은 참), 이는 정확히 반대를 의미합니다.
다양한 문서의 구문에 대한 깊은 이해입니까, 아니면 컴파일러에서의 구문에 대한 깊은 이해입니까?
물어볼 필요가 없습니다. 컴파일러여야 합니다!
그러면 당연히 문서보다 문법에 따라 파싱된 구문 트리를 통해 문법을 배우는 것이 더 좋습니다.
이는 정규식의 경우에도 마찬가지이며, 다른 문법을 학습할 때도 마찬가지입니다. AST를 사용하여 문법을 학습할 수 있으면 설명서를 읽을 필요가 없습니다.