본문 바로가기
Development/Free Topic

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

by 곽동현 이스텔리앙 2014. 6. 17.

# 정규식 문법 document
https://github.com/google/re2/wiki/Syntax

https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D



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

- 너무 심각하게 복잡한 기능이 필요한 정규식은 쓰지 않는 것이 답이다. 그러나 정말로 해야한다면 정규식에 대한 매우 높은 이해도가 필요하다.

- python을 쓸 수만 있다면, 정규식보다 훨씬 더 빠르고 정확하게 구현할 수 있다. 정규식은 최소한으로만 쓰는 것이 건강에 이롭다.

https://codeday.me/ko/qa/20190403/229820.html



# 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 변수로 뽑아준다.

https://hashcode.co.kr/questions/1440/%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4



## Substring 추출/합성을 위한 기능, $1

ex) =regexreplace(J2,"([""]?)([^""]*)([""]?)","$2")

(패턴)의 번호를 $N으로 지정하여, 해당 패턴으로 검출된 string을 가져온다. 예를 들어 위 구문에서는 (괄호)가 3개 있고, 여기서 $2를 입력하면 2번 째 괄호의 text를 가져온다. $0의 경우 전체 문장을 의미한다.

https://stackoverflow.com/questions/5982824/what-does-1-2-etc-mean-in-regular-expressions





# 실전 고급 테크닉
## 여러개의 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))


https://www.extendoffice.com/documents/excel/1052-excel-find-nth-occurrence.html



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

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



## Blank 개수 세기

=COUNTIF($B$2:B2, "")

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

https://www.ablebits.com/office-addins-blog/2014/07/02/excel-countif-examples/



# 참고

http://blog.naver.com/lucky996?Redirect=Log&logNo=10187238748

http://cafe.naver.com/wankyu/532

https://delicious.com/mwultong/regex





파이썬 정규식

https://www.guru99.com/python-regular-expressions-complete-tutorial.html

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'

예를 들어 위와 같은 표현은, "숫자, 공백, 숫자"의 패턴을 찾는 것이고, 여기서 첫번째와 두번 째 숫자에 \1과 \2라는 패턴을 지정한 것이다. 그래서 두 숫자 사이의 공백문자를 제외하고, 남은 두 숫자만 남기도록 한 것이다.


https://stackoverflow.com/questions/14007545/python-regex-instantly-replace-groups










댓글0