advanced regexp

고급 정규식

참고http://www.regular-expressions.info/conditional.html

주석

(?#comment)

괄호로 둘러싸진 ?#로 시작하는 단어는 그냥 주석으로 매치패턴에 포함되지 않는다.

a(?#foobar)b ==> ab

그룹 브랜치

(?|정규식패턴)

브랜치 리셋 그룹안에 들어있는 복수의 대체안 중 하나가 매칭되면 해당 그룹을 선택한다.

(x)(?|(a)|(bc)|(def))2

xaa, xbcbc, xdefdef와 매칭된다.

(x)((a)|(bc)|(def))와 차이가 없는데?

아토믹 그룹

패턴1(?>패턴2)

다른 거 없어보이지만, (?> ...) 이 부분이 그룹으로 잡히지는 않는다.

포지티브 전진검색

패턴1(?=패턴2)

“패턴1패턴2″가 나란히 있는 경우에만 패턴1을 매치한다. 예를 들어

i(?=n)

은 n 앞에 있는 i만 검색한다. it, is, ie 등의 i는 매치하지 않는다.

네거티브 전진검색

반대로, 주어진 패턴이 뒤에 없는 경우만 검색 전진 검색 패턴은 그룹으로 계산되지 않는다.

패턴1(?!패턴2)

포지티브 선행검색

특정 글자가 앞에 있는 패턴만 검색한다.

(?<=패턴2)패턴1

패턴2가 앞에 있는 패턴1을 찾는다.

(?<=i)n

은 앞에 i가 오는 n만 찾는다. on, an 의 n은 검색하지 않는다.

네거티브 선행 검색

(?<!패턴2)패턴1

반대로 패턴2가 앞에 없는 패턴1을 매치한다.

선후행 검사를 사용하면 괄호문자를 포함하지 않는 괄호내의 글자만 추출이 가능하다.
(?<=()([^()]+)(?=))

HTML 태그가 아닌 문자열 추출하기.

(?<=^|>)[^<>]+?(?>=$|<)

그룹 검색 조건

(패턴1)(?(패턴1에의한 그룹)패턴2|패턴3)

선행한 패턴1에의한 매칭 그룹이 있을 때, 패턴2가 그렇지 않은 경우에 패턴3을 매칭하려한다.

다음 예를 보자

(good)boy(/good) is a (study)student(/study)

HTML 태그와 유사하게 괄호태그를 사용하여 감싼 단어들이 있다. 이들을 찾는 패턴은 다음과 같다.

(((w+)))([^()]*)(?(1)(/2))
 ~~~~~~~~~  ~~~~~~~~    ~  ~~~~~~
 |  ~~~       ^그룹3    |  | ~~
 |   ^그룹2             |     ^정규식내에서 그룹번호는 1과 같이 쓴다.
 그룹1                  조건의 그룹번호는 번호만 쓴다

정규식에서의 그룹을 사용한 if~then~else 문은 다음과 같이 쓴다.

(?(그룹번호) 그룹매칭이 있을 때 패턴 | 그룹매칭이 없을 때 패턴 )

그럼 위의 식은 다음과 같이 나눠서 해석할 수 있다.

  • 첫번째 그룹은 괄호로 둘러싼 단어가 있는지를 매칭한다.
  • 첫번째 그룹안에 있는 두번째 그룹은 괄호로 둘러싸진 단어 자체가 된다.
  • 세번째 그룹은 그 이후의 괄호가 아닌 문자들의 연속이다.
  • 그 뒤에는 그룹1, 즉 괄호로 둘러싼 단어(시작태그)가 있을 때, (/시작태그)의 형태로 닫는 태그가 있는지를 검사한다.

따라서 예문에서는 (good)boy(/good), (study)student(/study) 가 매칭된다. 만약 열고 닫는 태그의 이름이 다르면 매칭되지 않는다.

**맵핑된 그룹을 “바꾸기”할 때는 통상 $1과 같은 식을 쓴다.

그룹에 이름 붙이기

(?<그룹이름>패턴1)

위의 형태로 쓰는 경우, 매칭된 그룹을 번호가 아닌 그룹으로 맵핑할 수 있다.

(?<number>d)?a(?(number)bc|d)

위 정규식은 1abcad에 매칭된다.