정규식 lookahead, lookbehind 및 원자 그룹


314

정규식 본문에서 이러한 것들을 찾았지만 사용할 수있는 단서가 없습니다. 누군가가 예를 들어서 어떻게 작동하는지 이해할 수 있습니까?

(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group

18
정규식 웹 사이트에 왜 이와 같은 간단한 테이블이 없습니까? 대신 설명하는 텍스트 블록 만 있습니다. regular-expressions.info/lookaround.html
Whitecat

3
@Whitecat 시도 : regex101.com regexr.com
Andrew

답변:


851

주어진 문자열 foobarbarfoo:

bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)

당신은 또한 그들을 결합 할 수 있습니다 :

(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)

정의

미리 긍정적으로 봐 (?=)

표현식 B가 따르는 표현식 A를 찾으십시오.

A(?=B)

앞서 부정적인 것을 봐 (?!)

표현식 B가 따르지 않는 표현식 A를 찾으십시오.

A(?!B)

긍정적으로 봐 (?<=)

표현식 B가 앞에 오는 표현식 A를 찾으십시오.

(?<=B)A

부정적인 뒤를 봐 (?<!)

표현식 B가 선행하지 않는 표현식 A를 찾으십시오.

(?<!B)A

원자 그룹 (?>)

원자 그룹은 그룹을 종료하고 그룹 내에서 첫 번째 일치 패턴 이후에 대체 패턴을 버립니다 (역 추적 사용 안함).

  • (?>foo|foot)s에 적용됨 foots은 첫 번째 대안과 일치하고 즉시 추적하지 않으므로 foo실패 s하고 역 추적이 비활성화되면 중지

비 원자 그룹은 역 추적을 허용합니다. 이후의 일치가 실패하면 전체 표현식에 대한 일치가 발견되거나 모든 가능성이 소진 될 때까지 역 추적 패턴을 사용하고 대체 패턴을 사용합니다.

  • (foo|foot)sfoots의지에 적용 :

    1. 첫 번째 대안과 일치하고 즉시 따르지 않는 foo대로 실패 하고 두 번째 대안으로 되돌아갑니다.sfoots
    2. 두 번째 대안과 일치 foot한 다음 s바로 다음과 같이 성공 foots하고 중지하십시오.

일부 자료

온라인 테스터


1
"두 번째 막대 찾기"는 무엇을 의미합니까? 표현식 / 문자열에는 막대가 하나만 있습니다. 감사합니다
ziggy

2
@ziggy 테스트 할 문자열은 "foobarbarfoo"입니다. 보시다시피 문자열에는 두 개의 foo와 두 개의 막대가 있습니다.
skyfoot 2019

4
원자 그룹이 필요할 때 누군가가 설명 할 수 있습니까? 첫 번째 대안과 만 일치해야하는 경우 여러 대안을 제공하려는 이유는 무엇입니까?
arviman

2
이 답변 에서 원자 그룹대한 더 나은 설명 . 이 편집적인 답변을 완성하기 위해 누군가가 여기에서 편집 할 수 있습니까?
피터 크라우스

5
이 답변은 심각한 정규식 절단이 필요한 프로젝트를 끝냈을 때 필수적이었습니다. 이것은 둘러보기에 대한 훌륭하고 간결한 설명입니다.
Tom Coughlin

215

둘러보기는 너비가 0 인 어설 션입니다. 그들은 정규식 (앞 또는 뒤를 기준으로 현재 위치의 오른쪽 또는 왼쪽으로)을 확인하고 일치하는 것이 발견되면 (긍정적이든 부정적이든에 따라) 성공 또는 실패하고 일치하는 부분을 버립니다. 그들은 어떤 문자도 소비하지 않습니다-정규 표현식에 대한 일치는 (있는 경우) 동일한 커서 위치에서 시작됩니다.

읽기 regular-expression.info 자세한 내용은.

  • 긍정적 인 예견 :

통사론:

(?=REGEX_1)REGEX_2

REGEX_1이 일치하는 경우에만 일치합니다. REGEX_1과 일치하면 일치가 삭제되고 REGEX_2 검색이 동일한 위치에서 시작됩니다.

예:

(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}

REGEX_1은 [a-z0-9]{4}$4 개의 영숫자 문자와 줄 끝이 일치합니다.
REGEX_2는 [a-z]{1,2}[0-9]{2,3}1 ~ 2 개의 문자 다음에 2 ~ 3 개의 숫자와 일치합니다.

REGEX_1은 문자열 길이가 실제로 4인지 확인하지만 문자를 소비하지 않으므로 REGEX_2에 대한 검색이 동일한 위치에서 시작됩니다. 이제 REGEX_2는 문자열이 다른 규칙과 일치하는지 확인합니다. 미리 보지 않으면 길이가 3 또는 5 인 문자열과 일치합니다.

  • 부정적 예측

통사론:

(?!REGEX_1)REGEX_2

REGEX_1이 일치하지 않는 경우에만 일치합니다. REGEX_1을 확인한 후 REGEX_2에 대한 검색이 동일한 위치에서 시작됩니다.

예:

(?!.*\bFWORD\b)\w{10,30}$

미리보기 부분 FWORD은 문자열에서를 확인 하고 찾지 못하면 실패합니다. 찾지 못하면 FWORD미리보기가 성공하고 다음 부분은 문자열 길이가 10에서 30 사이이고 단어 문자 만 포함하는지 확인합니다.a-zA-Z0-9_

Look-Behind는 Look-Ahead와 유사합니다. 현재 커서 위치 뒤에서 만 보입니다. javascript와 같은 일부 정규 표현식은 look-behind assertion을 지원하지 않습니다. 그리고 그것을 지원하는 대부분의 맛 (PHP, Python 등)은 뒤에 보이는 부분의 길이가 고정되어 있어야합니다.

  • 원자 그룹은 기본적으로 토큰이 일치하면 그룹의 후속 토큰을 버리고 잊습니다. 원자 그룹의 예는이 페이지를 확인하십시오.

설명에 따라 자바 스크립트에서 작동하지 않는 것 같습니다 ./(?=source)hello/.exec("source...hummhellosource ") = null. 당신의 설명이 맞습니까?
Helin Wang

@HelinWang 그 설명은 정확합니다. 정규 표현식은 동시에 소스와 hello 문자열을 기대합니다!
Amarghosh 2016 년

@jddxf 정교한 관리가 필요하십니까?
Amarghosh

@Amarghosh 본인은 "정규식 (앞 또는 뒤를 기준으로 오른쪽 또는 왼쪽으로)을 확인하고 일치하는 것이 발견 될 때 (긍정적이든 부정적이든 기준으로) 성공 또는 실패하고 일치하는 것을 버립니다 일부.". 따라서 lookahead는 현재 위치의 오른쪽으로 정규 표현식을 확인하고 긍정적 lookahead의 구문은 x (? = y)
jddxf

@Amarghosh 는 다음에 오는 (?=REGEX_1)REGEX_2경우에만 일치합니다 . REGEX_2 REGEX_1
aandis

0

빠르게 둘러보기.
lookahead와 lookbehind를 구별하는 방법? 나와 함께 2 분 둘러보기 :

(?=) - positive lookahead
(?<=) - positive lookbehind

가정

    A  B  C #in a line

이제 우리는 B에게 묻습니다. 당신은 어디에 있습니까?
B는 위치를 선언하는 두 가지 솔루션을 제공합니다.

하나, B는 A보다 앞서고 C는 결합합니다.
두, B는 C보다 앞서고 (전망) A 뒤에 있습니다.

보시다시피, 뒤와 앞은 두 솔루션에서 반대입니다.
정규식은 솔루션 2입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.