정규식을 사용하여 문자열을 두 부분으로 나누려고합니다. 문자열의 형식은 다음과 같습니다.
text to extract<number>
나는 사용 (.*?)<
하고 있고 <(.*?)>
잘 작동하지만 정규식을 조금 읽은 후에 왜 ?
표현에 왜 필요한지 궁금해하기 시작했습니다 . 나는이 사이트를 통해 그들을 찾은 후에 만 그렇게 했으므로 차이점이 무엇인지 정확히 알 수 없습니다.
답변
욕심쟁이와 욕심없는 정량 자의 차이점입니다.
입력을 고려하십시오 101000000000100
.
사용하면 1.*1
, *
욕심 – 그것은 일치 할 때까지 철수 후 마지막에 모든 방법을 일치 할 것이다 1
당신을 떠나 1010000000001
.
.*?
욕심이 없습니다. *
아무것도 일치하지 않습니다, 그러나 그것은 일치 할 때까지 추가 문자를 일치하려고합니다 1
결국 일치 101
.
모든 한정사가 아닌 욕심 모드를 가지고 : .*?
, .+?
, .{2,6}?
, 심지어 .??
.
귀하의 경우 비슷한 패턴 <([^>]*)>
이보다 큰 부호 이외의 항목과 일치 할 수 있습니다 (엄격히 말하면 >
중간 <
및 사이 이외의 0 개 이상의 문자와 일치합니다 >
).
수량 자 치트 시트를 참조하십시오 .
답변
욕심과 비 욕심에
정규 표현식에서 기본적으로 반복하는 것은 욕심입니다 . 가능한 한 많은 담당자와 일치 시키려고 노력하고 이것이 작동하지 않고 역 추적해야 할 때 전체 패턴이 일치 할 때까지 한 번에 하나의 적은 담당자를 일치시킵니다. 녹이다. 결과적으로 경기가 마지막으로 이루어질 때 욕심 많은 반복은 가능한 한 많은 담당자와 일치 합니다.
?
에이 동작을 변경 정량 반복과 같은 비 욕심 도 불리는 꺼려 ( 예를 들면 자바 ) (때로는 “게으른”). 대조적으로,이 반복은 가능한 한 적은 수의 담당자와 일치 시키려고 시도 하며, 이것이 작동하지 않고 역 추적해야하는 경우, 한 번 더 담당자와 일치하기 시작합니다. 결과적으로 경기가 마지막으로 일어날 때 꺼리는 반복은 가능한 한 적은 담당자와 일치 합니다.
참고 문헌
예 1 : A에서 Z로
하자이 두 패턴을 비교 : A.*Z
와 A.*?Z
.
다음과 같은 입력이 주어집니다.
eeeAiiZuuuuAoooZeeee
패턴은 다음과 일치합니다.
A.*Z
수확량 1 회 :AiiZuuuuAoooZ
( rubular.com 참조 )A.*?Z
2 개의 일치 항목을 생성합니다 :AiiZ
및AoooZ
( rubular.com 참조 )
먼저 무엇에 초점을 맞추자 A.*Z
. 그 첫 번째 일치하는 경우 A
는 .*
, 욕심, 처음 시도되는 것은 많은으로 일치하도록 .
가능한 한.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Z
일치하지 않기 때문에 엔진이 역 추적 .*
한 다음 하나 더 적어야합니다 .
.
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
마지막으로 우리가 이것에 올 때까지 이것은 몇 번 더 발생합니다.
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
이제 Z
일치 할 수 있으므로 전체 패턴이 일치합니다.
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
대조적으로, 마지 못한 반복은 A.*?Z
처음 .
에는 가능한 한 적은 수를 맞추고 .
필요에 따라 더 많이 가져 갑니다. 입력에서 두 개의 일치 항목을 찾는 이유를 설명합니다.
다음은 두 패턴이 일치하는 것을 시각적으로 나타낸 것입니다.
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
예 : 대안
많은 응용에서, 상기 입력에서 두 개의 매칭이 요구되는 것이므로 .*?
, 욕심 대신에 꺼리는 것이 사용 .*
되어 오버 매칭 을 방지한다. 그러나이 특정 패턴의 경우 부정 문자 클래스를 사용하는 더 나은 대안이 있습니다.
패턴 A[^Z]*Z
은 또한 A.*?Z
위 입력에 대한 패턴 과 동일한 두 개의 일치 항목을 찾습니다 ( ideone.com 참조 ). [^Z]
불리는 무엇 인 부정 문자 클래스 는 모든 항목과 일치하지만, : Z
.
두 패턴의 주요 차이점은 성능에 있습니다. 더 엄격하면 부정 된 문자 클래스는 주어진 입력에 대해 한 가지 방식과 만 일치 할 수 있습니다. 이 패턴에 대해 탐욕 스럽거나 꺼리는 수정자를 사용하는 것은 중요하지 않습니다. 실제로 일부 맛에서는 더 나은 작업을 수행 할 수 있으며 소급 수량 자라고하는 것을 사용할 수 있습니다.
참고 문헌
예 2 : A에서 ZZ로
이 예제는 설명이 필요합니다. 동일한 입력에서 욕심, 꺼림 및 부정 문자 클래스 패턴이 어떻게 다르게 일치하는지 보여줍니다.
eeAiiZooAuuZZeeeZZfff
위의 입력과 일치합니다.
A[^Z]*ZZ
1 번 일치 :AuuZZ
( ideone.com에 표시 )A.*?ZZ
1 번 일치 :AiiZooAuuZZ
( ideone.com에 표시 )A.*ZZ
1 번 일치 :AiiZooAuuZZeeeZZ
( ideone.com에 표시 )
다음은 일치하는 내용을 시각적으로 나타낸 것입니다.
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
관련 주제
이것들은 관심있는 주제를 다루는 stackoverflow에 관한 질문과 답변에 대한 링크입니다.
수있는 하나의 욕심이 반복 outgreed 다른
답변
가지고 있다고 가정 해 봅시다.
<a></a>
<(.*)>
일치하는 a></a
위치와 <(.*?)>
일치 a
합니다. 후자는의 첫 번째 경기 후에 멈 춥니 다 >
. .*
다음 표현식이 하나 이상 일치하는지 확인합니다 .
첫 번째 표현식 <(.*)>
은 첫 번째 표현식과 일치 할 때 멈추지 않습니다 >
. 의 마지막 일치까지 계속됩니다 >
.