나는 grep과 awk가 NFA(Non-Deterministic) 정규식 기계를 사용한다는 인상을 받았습니다.
이 페이지 중간에 있는 이미지정규식 일치는 간단하고 빠를 수 있습니다.그 사실을 확인합니다.
첫 번째 교체가 일치하면 NFA 구현이 중지될 수 있는 것으로 알려져 있습니다. 예를 들어 링크된 기사의 NFA 머신은 다음과 같습니다.예를 들어, abab|abbb에 대한 NFA를 고려해보세요.:
정규식에 해당하는 것은 첫 번째 와 일치할 때 abab|abbb
문자열과 오른쪽의 일치 상태에 도달합니다 . 그 시점에서는 끝까지 도달하여 매칭 상태로 정지하게 된다(S10). 또 다른 일치가 가능 하더라도 더 많은 입력을 테스트할 필요가 없습니다 .ababbbb
abab
abbb
즉, 이 코드에서는 다음과 같습니다.
echo 'catfish' | grep -Eo 'cat|catfish'
결과는 이어야 cat
하지만 입니다 catfish
. 교대를 바꿔도 결과는 동일합니다.
grep 정규식 엔진이 항상 가장 긴 일치 항목을 찾는 이유는 무엇입니까?
그리고 그 기본값을 변경할 수 있나요?
답변1
표준에서는 실제로 가장 긴 일치를 요구하기 때문에 POSIX 호환 grep
또는 으로 이를 수행할 수 있는 방법이 없다고 생각합니다 (예를 들어 맨페이지 참조).awk
regex(7)
예를 들어 프로그램과 정규 표현식을 awk
수정하여 원하는 출력을 얻을 수 있습니다.awk
echo 'SetValue' | awk '{ if (match($0, /Set(Value)?/)) { print substr($0, RSTART, 3); }
pcregrep
이 상황에서는 다음을 사용하여 번호가 매겨진 하위 그룹을 지정할 수 있는 (pcre perl 호환 정규 표현식 라이브러리의 일부) 에 도달합니다 -o
.
echo SetValue | pcregrep -o1 '(Set)(Value)?'
또는 pcre에는 탐욕스럽지 않은 일치를 위한 구문이 있기 때문에
echo SetValue | pcregrep -o0 'Set(Value)??'
답변2
내가 이해할 수 있는 한, 실제로 다음과 같은 것들이 있다는 것이 밝혀졌습니다.두 개의 NFA 머신:
기존 NFA 엔진
역추적 및 다음을 수행하는 NFA 머신입니다.가장 긴 왼쪽 일치 항목이 항상 존중될 수는 없습니다..POSIX NFA 엔진
모든 상태를 병렬로 처리하고 입력 문자열에서 일치하는 항목을 선택할 수 있는 비역추적 NFA 엔진입니다. 가장 왼쪽에서 가장 긴 일치 항목을 선택하는 것은 POSIX 요구 사항입니다.
그러나 DFA 역추적 시스템(Perl)은기하급수적으로 폭발하다(2^n)정규식이 아닌 텍스트에 의해 구동되며 첫 번째 대체 항목을 선택할 수도 있고 선택하지 않을 수도 있습니다.
또한DFA는 가능한 모든 일치 항목을 동시에 인식합니다..
그리고 질문에 링크된 기사의 저자는re2 구현은 대체를 다음과 같이 정의합니다: x|y ==> x 또는 y(x 선호)즉, 첫 번째 교대를 선호합니다.
따라서 결론적으로 특정 구현에 따라 대체 부분이 선택될 NFA 또는 DFA를 실제로 연관시킬 수 있는 방법이 없습니다.
그리고 아니요. 특정 구현에 기본값을 변경하도록 지시하는 방법을 찾지 못했습니다.
관련된: