Search
Duplicate

정규표현식, 정규식, 엑셀 고급기능

Created
4/23/2021, 7:19:00 PM
Tags
Empty

정규표현식(Regular Expression, Regex, 정규식)

정규식 문법

복잡한 정규식의 사용에 대해

너무 심각하게 복잡한 기능이 필요한 정규식은 쓰지 말고, 그냥 python 프로그래밍으로 해결 하는 것이 훨씬 나은 방법이다. 그러나 정말 어쩔 수 없이 해야만한다면 정규식에 대한 매우 높은 이해도가 필요하다.
Python을 쓴다면, 정규식보다 훨씬 더 구현이 빠르고 정확하며, 디버깅, 유지보수, 협업이 용이해진다. 특히 너무 복잡한 문제에는 가능한 정규식은 사용하지 않는 것이 정신 건강에 이롭다.

Regex를 이해하는 핵심 원리

기본적으로 정규식은 항상 (찾을패턴 + 개수)의 형태로 조합하여 텍스트를 검색한다.
패턴의 검출은 string의 뒷쪽에서부터, 즉 역순으로 적용된다.패턴은 항상 가장 큰 범위의 string에서부터 적용된다.(즉 패턴을 최대한 넓게 적용하려한다.)
예를들어 REGEXREPLACE은 항상 뒤에서부터, 가장 큰 범위로, multiple하게 적용된다.

문자 지정 문법

[ ]안에 원하는 pattern을 입력한다.
| 은 '또는'을 의미한다.

예약어(키워드)

\n: 줄바꿈 문자(엔터를 지우고싶으면 \n을 찾아서 스페이스로 교체)\s: 공백문자
\t: tab문자
\d: 숫자

문자를 찾는 개수 지정 하기

: 앞의 대상을 0~N개 찾음
? : 앞의 대상을 0 또는 1개 찾음
+ : 앞의 대상을 1개이상 찾음

찾을 문자 지정 패턴 예시

. : 줄바꿈 이외에 모든 문자
[a-z]* : 소문자로 시작하는 모든 글자를 찾음
[a-z|A-Z]*: 모든 알파벳
[가-힣]* : 모든 완성형 한글을 찾음[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]: 모든 한글을 찾음(https://eblee-repo.tistory.com/40)
[0-9]* : 모든 숫자[^X]* : X를 제외한 나머지 모든 문자

실제 예제

1. image_ 뒤에 숫자 세개 찾기
image_[0-9][0-9][0-9]
2. image_ 뒤에 모든 숫자 찾기
image_[0-9]*
3. image_ 뒤에 모든 문자 찾기
image_.*
4. korea라는 단어가 등장하는 앞줄과 뒷문장 찾기(두 줄 찾기)
.*\r\nkorea.*\r

정규식 고급 기능

복잡한 수준의 정규식 처리를 하기 위해서는 거의 항상 등장하는 패턴이 바로 아래의 두가지이다. 이 두가지를 완전히 이해해야만 아주 복잡한 기능을 구현할 수 있다. 그러나 여기서도 주의할점은
(?P<name>...) : 뒤에 나오는 ...조건에 매칭되는 문자열을 name 변수로 뽑아준다.
Substring 추출/합성을 위한 기능, $1
ex) =regexreplace(J2,"([""]?)([^""]*)([""]?)","$2")
(패턴)의 번호를 $N으로 지정하여, 해당 패턴으로 검출된 string을 가져온다. 예를 들어 위 구문에서는 (괄호)가 3개 있고, 여기서 $2를 입력하면 2번 째 괄호의 text를 가져온다. $0의 경우 전체 문장을 의미한다.

실전 고급 테크닉

여러개의 special tag를 발견하고, 원하는 string만 뽑아오기.

ex) <timeRelative>지금</> <numPeople>여섯명</> 예약하려고 하는데요. <seatType>룸으로</> 가능한가요?
-> 지금 여섯명 예약하려고 하는데요. 룸으로 가능한가요?
= REGEXREPLACE(I2, "<[a-z|A-Z]*>([^<]*)</>","$1")
패턴을 정의할 때, 여러 개의 tag가 하나로 인식되지 않도록, 범위를 [^<]* 이렇게 제한하는 것이 핵심이다.

큰따옴표 안의 글자만 가져오기

=REGEXREPLACE(J8,"(.*)""(.*)""(.*)", "$2")
단, 이렇게하면 가장 마지막에 매칭되는 string만 가져옴.

엑셀 응용 테크닉

Find를 통해 N번째 문자의 index알아내기

찾고 싶은 문자가 "_"이라면, 4번째 "_"을 스페셜토큰 ";"으로 바꾼다음, 그것의 위치를 검색한다.
=find(";",SUBSTITUTE(G2,"_",";",4))

중복해서 등장하는 아이템 개수 세기(유니크 아이디 만들때 사용)

=COUNTIF($E$2:E2, E2)-1

Blank 개수 세기

=COUNTIF($B$2:B2, "")
= COUNTIF($B$2:B2, "<>"&"*")

참고

1. python 정규식 함수들

match(): 무조건 전체 문서의 맨 앞부분에 대해서만 정규식 검사를 한다. 따라서 굉장히 사용용도가 제한적이고 기능이 약하다. 안쓰길 추천한다.
search(): match와 동일하나, 문서의 모든 영역을 탐색하여 해당하는 패턴의 문자를 찾는다.
findall(): search와 동일하나, 문서의 모든 영역을 탐색하여 해당하는 패턴의 모든 문자를 찾는다. 따라서 findall 만 있으면, match나 search는 필요없다.
sub(): 매우 활용도가 높은 함수로, 주어진 string을 내가 원하는 방식대로 편집할 수 있다. 즉 특정한 패턴을 삭제하거나, 문자열을 재조합하거나, 수정하거나 하는 것이 가능하다.

2. 예시

sub에 대한 추가 설명

우선 파이썬에서는 정규식의 replace가 sub에 해당한다. 차이점이 있다면, $1 대신 \1 으로 패턴을 인덱싱하고, 패턴을 지칭할 때 P라는 글자 없이 물음표와 괄호만으로 가능하다는 점이다. 즉 (.*?) 과 같이 입력하면 된다.
string1 = "123 456" re.sub(r"(\d*)\s*(\d*)", r"\1\2", string1) => '123456'
Plain Text
예를 들어 위와 같은 표현은, "숫자, 공백, 숫자"의 패턴을 찾는 것이고, 여기서 첫번째와 두번 째 숫자에 \1과 \2라는 패턴을 지정한 것이다. 그래서 두 숫자 사이의 공백문자를 제외하고, 남은 두 숫자만 남기도록 한 것이다.
TOP