Sangmun

정규표현식 심화 본문

개발/정규표현식

정규표현식 심화

상상2 2023. 1. 23. 12:28

그루핑

기존 문서에서 설명하였던 메타 문자들만으로는 하나의 문자에만 반복 혹은 규칙을 적용할 수 있었는데 문자열을 그룹핑에서 메타 문자를 적용할 필요가 있을 때 사용하는 것이 그루핑이다.

 

p = re.compile('(ABC)+')
m = p.search('ABCABCABC OK?')
print(m)
<re.Match object; span=(0, 9), match='ABCABCABC'>
print(m.group())
ABCABCABC

위의 예시처럼 (ABC)가 반복되는 구간을 찾을 수 있다.

 

또한 다음은 전화번호를 탐지하는 정규표현식 패턴인데 이중에서 이름만 뽑아내고 싶다면 아래와 같이 그루핑을 이용할 수 있다.

p = re.compile(r"(\w+)\s+\d+[-]\d+[-]\d+")
m = p.search("park 010-1234-1234")
print(m.group(1))
park

이름에 해당하는 \w+ 부분을 그룹 (\w+)으로 만들면 match 객체의 group(인덱스) 메서드를 사용하여 그루핑 된 부분의 문자열만 뽑아낼 수 있다. group 메서드의 인덱스는 다음과 같은 의미를 갖는다.

 

* 그루핑된 문자열 재참조

또한 그루핑한 문자열을 재참조하여서 반복하는 문자열을 매칭할 수 도 있다.

정규식 (\b\w+)\s+\1 (그룹) + " " + 그룹과 동일한 단어와 매치됨을 의미한다

p = re.compile(r'(\b\w+)\s+\1')
p.search('Paris in the the spring').group()
'the the'

 

* 그루핑된 문자열에 이름 붙이기

그룹에 이름을 넣어서 참조를 할 때 이름으로도 할 수가 있다.

p = re.compile(r"(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group("name"))
park

 

전방 탐색 후방 탐색

* 긍정형 전방 탐색 : ((?=...)) -...에 해당되는 정규식과 매치되어야 하며 조건이 통과되어도 문자열이 소비되지 않는다.

긍정형 전방 탐색을 하면 'http://google.com'에서 ':'를 기준으로 http만 추출하는 것이 가능하다.

p = re.compile(".+(?=:)")
m = p.search("http://google.com")
print(m.group())
http

* 부정형 전방 탐색 : ((?!...)) -... 에 해당되는 정규식과 매치되지 않아야 하며 조건이 통과되어도 문자열이 소비되지 않는다.

. bat이나. exe로 끝나는 확장자 파일만을 제외해서 탐지하고 싶으면 아래의 정규식을 이용할 수 있다.

.*[.](?!bat$|exe$).*$

* 후방 탐색

(?<=...) 구문을 사용하면 매칭된 문자열 뒤의 문자열을 리턴해준다.

p = re.compile(r"(?<=:).+")
m = p.search("http://google.com")
print(m)
<re.Match object; span=(5, 17), match='//google.com'>

 

문자열 바꾸기

sub 메서드를 사용하면 정규식과 매치되는 문자열을 다른 문자로 치환할 수 있다.

p = re.compile('(blue|white|red)')
p.sub('colour', 'blue socks and red shoes')
'colour socks and colour shoes'

sub 함수의 첫 번째 인자가 바꿀 문자열, 두 번째 문자열이 대상이다.

치환 횟수를 제한하고 싶으면 아래와 같이 옵션을 주면 된다.

p.sub('colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes

Greedy와 Non - Greedy

정규표현식의 메타 문자들은 기본적으로 greedy하다고 할 수 있다. 매칭이 되는 가능한 문자열중 최대한 긴 것을 리턴해준다.

 

아래의 예를 보면 우리가 찾고 싶었던것은 <html>이었을 수도 있지만 전체 문자열 s도 정규표현식 패턴에 매칭이 됨과 동시에 가장 긴 매칭이 되는 문자열임으로 리턴이 되는 것을 확인할 수 있다.

s = '<html><head><title>Title</title>'
len(s)
32
print(re.match('<.*>', s).span())
(0, 32)
print(re.match('<.*>', s).group())
<html><head><title>Title</title>

하지만 다음과 같이 ?문자를 같이 사용해 주면 메타 문자의 탐욕을 제한할 수 있다.

print(re.match('<.*?>', s).group())
<html>

 

 

https://wikidocs.net/4309

 

08-3 강력한 정규 표현식의 세계로

이제 07-2에서 배우지 않은 몇몇 메타 문자의 의미를 살펴보고 그룹(Group)을 만드는 법, 전방 탐색 등 더욱 강력한 정규 표현식에 대해서 살펴보자. [TOC] ## 메…

wikidocs.net

 

'개발 > 정규표현식' 카테고리의 다른 글

정규표현식 기초 python re 모듈  (0) 2023.01.22
정규표현식 기초 (메타문자)  (0) 2023.01.22
Comments