re는 문자열 내 특정 패턴을 검색, 치환, 제거할 수 있는
파이썬 정규 표현식(Regular Expression) 라이브러리이다.
re 가 패턴을 인식하는 방법은 다음과 같다.
1) 정규식 작성
: 특정 문자를 인식하기 위한 패턴을 정규식으로 작성한다. (내가 할 일)
2) re 에 정규식 적용
: 작성한 패턴을 re 에 적용시키면 re 는 이를 가지고 정규식 객체를 생성한다.
3) 패턴 감지
: 생성된 정규식 객체는 자동으로 문자열 내 해당 패턴을 감지할 수 있다.
즉, 내가 작성한 정규식을 토대로 문자열 내 패턴을 감지하는 것이다.
코딩하다보면 한 번 쯤은 꼭 정규식을 접하게 되는데
뭔가 더럽게(?) 생긴데다 규칙이 잘 외워지지도 않는다.
(그런데도 패턴 인식에 있어서 정말 많이 사용되는 표현식이다.)
내가 자주 사용하는 정규식 규칙들을 정리해 봄!
<선택>
표현식(규칙) | 뜻 | 적용 예시 | 적용 예시 해석 |
| | or | A|B | A 또는 B |
[] | or (대괄호 안에 있는 문자열) | [ABC] | A 또는 B 또는 C |
<반복>
표현식(규칙) | 뜻 | 적용 예시 | 적용 예시 해석 |
* | 바로 앞 문자열 0개 이상 반복 | BA* | B, BA, BAA, ... |
+ | 바로 앞 문자열 1개 이상 반복 | BA+ | BA, BAA, ... |
? | 바로 앞 문자열 0 or 1개 반복. 즉, 나오거나 안나오거나. |
BA? | B, BA |
{n} | 바로 앞 문자열 n개 반복 | AB{2} | ABB |
{n,} | 바로 앞 문자열 n개 이상 반복 | AB{2,} | ABB, ABBB, ... |
{n,m} | 바로 앞 문자열 n개 이상 m개 이하 반복 | A(BC){2,4} | ABCBC, ABCBCBC, ABCBCBCBC |
<인식 타입>
표현식(규칙) | 뜻 |
\s | 공백(space) 한 개 |
\w | 문자 or 숫자 한 개 |
\W | 문자 or 숫자가 아닌 것 |
\d | 숫자 한 개 |
\D | 숫자가 아닌 문자 한 개 |
. | 모든 문자 한 개 |
^ | 문자열 시작 |
$ | 문자열 끝 |
이제 이 정규식 표현들을 적용할 re 의 주요 함수들을 알아보자.
1. re.search (검색)
re.search(pattern, string)
문자열을 스캔하여 정규식 패턴이 일치하는 첫 번째 위치를 찾는다. (찾지 못하면 None 반환)
예를 들어 날짜를 인식하는 정규식 패턴을 search 에 적용하면,
pattern = "([0-9]+년)\s*([0-9]+월)\s*([0-9]+일)"
a = re.search(pattern, "2021년 12월 29일 입니다. 내일은 2021년 12월 30일 이에요.")
# print(a)
# <re.Match object; span=(0, 13), match='2021년 12월 29일'>
위와 같이 첫 번째 인식한 결과를 객체로 반환한다.
반환된 객체에서 유용한 정보를 뽑아내보자.
# 인식패턴 시작 index
a.start() # 0
# 인식패턴 끝 index
a.end() # 13
# 인식패턴 문자열 출력
a.group() # '2021년 12월 29일'
# 그 외 부분적으로 인식된 패턴들 모음
a.groups() # ('2021년', '12월', '29일')
.groups() 를 보면 알 수 있듯이, re 는 전체 패턴에 대한 인식 결과물 외에도
부분적인 패턴 일치 결과물들도 저장해두는 걸 알 수 있다.
부분 일치 결과물들도 활용이 가능하다는 점 참고!
a.group() # '2021년 12월 29일'
a.group(0) # '2021년 12월 29일'
a.group(1) # '2021년'
a.group(2) # '12월'
a.group(3) # '29일'
a.group(4) # IndexError: no such group
어쨌거나 우리가 원하는 전체 패턴 인식 결과물은 .group() 혹은 .group(0) 으로 얻을 수 있다.
2. re.match (검색)
re.match(pattern, string)
search 와 유사하게 검색의 기능을 하지만 문자열의 시작 부분에서만 일치를 검사한다.
(search 는 문자열의 아무 곳에서나 일치하면 인식 가능)
re.match("c", "abcdef") # 아무 것도 반환하지 않음
re.match("c", "cdef") # <re.Match object; span=(0, 1), match='c'>
# search 는?
re.search("c", "abcdef") # <re.Match object; span=(2, 3), match='c'>
3. re.split (쪼개기)
re.split(pattern, string)
문자열을 패턴 기준으로 쪼갠다.
pattern = "[0-9]"
a = re.split(pattern, "오늘은 29일 이에요")
# a
# ['오늘은 ', '', '일 이에요']
숫자를 인식하는 패턴으로 split 을 적용하면 위와 같다.
2 와 9 를 기준으로 문장이 쪼개진 것을 알 수 있다. (리스트로 반환)
4. re.sub (치환)
re.sub(pattern, repl, string)
string 에서 pattern 을 찾아서 repl 로 치환한다.
pattern = "[0-9]"
b = re.sub(pattern, "a", "오늘은 29일 이에요")
# b
# '오늘은 aa일 이에요'
숫자를 찾아 'a' 로 치환한 것을 알 수 있다.
5. re.compile (컴파일)
정규식 패턴을 정규식 객체로 컴파일한다.
prog = re.compile(pattern)
정규식 객체 prog 를 가지고 위에서 설명한 search, match, split 등등을 할 수 있다.
prog = re.compile(pattern)
a = prog.search("2021년 12월 29일 입니다.")
# print(a)
# <re.Match object; span=(0, 13), match='2021년 12월 29일'>
이런 식으로, 컴파일한 객체에 위 함수들을 동일하게 적용하면 된다.
Q. re.search vs 정규식객체에서 search 호출 차이점
그럼 위처럼 re.search 를 사용하는 것과 컴파일된 객체에서 search 를 호출하는 건 어떤 차이가 있을까?
# 1
prog = re.compile(pattern)
a = prog.search("2021년 12월 29일 입니다.")
# 2
a = re.search(pattern, "2021년 12월 29일 입니다.")
기능상으로 동일하다.
다만, 하나의 정규식 패턴이 여러 번 사용될 때 compile 을 사용하는 것이 효율적이다.
pattern = "([0-9]+년)\s*([0-9]+월)\s*([0-9]+일)"
# 1
prog = re.compile(pattern)
a = prog.search("2021년 12월 29일 입니다.")
b = prog.search("내일은 2021년 12월 30일 입니다.")
# 2
a = re.search(pattern, "2021년 12월 29일 입니다.")
b = re.search(pattern, "내일은 2021년 12월 30일 입니다.")
아래의 경우처럼 re.search 를 계속 하면
동일한 패턴에 대해 정규식 객체를 계속해서 생성하게 되지만,
위의 경우처럼 생성한 정규식 객체를 재활용하면 보다 효율적일 수 있다.
광고 cIick은 토람코에 큰 힘이 됩니다 ♥
':: python' 카테고리의 다른 글
python :: 파이썬 웹페이지 url 에서 json 데이터 가져오기 (구글 애드센스 sellers.json 에서 자신의 사용자 정보 찾기) (0) | 2022.01.02 |
---|---|
python :: shutil.copy 리눅스 네트워크 드라이브로 파일 복사 시 WinError 해결 (0) | 2021.12.30 |
python :: list 형태의 string(문자열)을 list type 으로 변환하기 (2) | 2021.12.22 |
python :: 회사 프록시(proxy) 환경에서 파이썬 패키지 다운로드, api 호출 성공하기 (0) | 2021.11.30 |
python :: 파이썬 Bytes to String 변환하기 (2) | 2021.11.18 |