티스토리 뷰

 

이 글은 크게 regex에 대한 요약과 Python에서 regex를 쓰는 부분 두개로 나누어놨다.

regex에 관련된 유용한 사이트도 글의 마지막 부분에서 소개하려고 한다.

1. Regex 정리

이 부분은 완전 기본이라서 빠르게 정리하고 넘어가려고 한다.

[]:문자 클래스. 그룹보다 얘를 쓰는게 좋다! ex) [0-9][a-z][A-Z][가-힣][abc]
^을 쓰면 반대 의미가 된다. ex) [^a-z]
 
[\d]: 숫자 
[\D]: 숫자 외 모든것

\.: 줄바꿈 문자 제외 어떤 글자
\ : 특수 문자가 아닌 어떤 문자

\w: 알파벳과 숫자
\W: 그외

[\s]. :공백
\S: 공백 외

개수를 지정해보자

. : 1번(\n 제외)
? : 0번 혹은 1번
* : 0번 이상
+ : 1번 이상
{n} : n번 반복
{2,3} : 2~3번

어디서 나올지를 지정해보자

regex의 단어는 위치는 지정해서 판단하지 않는다.

'unsuccessful' 이라는 단어에서 'successful'이라는 Regex를 입력해도 true이다.

따라서 위치를 지정해줘야 원하는 결과를 얻을 수 있다.

시작: ^, 끝: $은 외우면 자주 사용하는 표현이다.

문장
^Ya: 문장의 시작에서 쓰이는 Ya
Ya$: 문장의 끝에서 쓰이는 Ya

!단어
\BYa: 단어 앞에서 쓰이지 않는 Ya
Ya\B: 단어 뒤에서 쓰이지 않는 Ya


메타문자 \b
띄어쓰기 단위 중 단어 앞에서 쓰이는 문자열만 선택하고 싶다면?또는 띄어쓰기 단위 중 단어 뒤에서 쓰이는 문자열만 선택하고 싶다면?ex ) \bclass\b => no class at은 가능, classify는 불가ex ) Ya\B => Ya ya YaYaYa 중 제일뒤의 Ya하나만ex ) Ya\b => Ya ya YaYaYa 중 제일 뒤가 아닌 Ya, Ya

단어
\bYa: 단어 앞에서 쓰이는 Ya
Ya\b: 단어 뒤에서 쓰이는 Ya

이걸 쓰려면 Multiline옵션을 설정해야 한다.

/{}/gm

  • / 를 쓰고싶으면 \/로 써야함

 

추가 처리를 위해서 Group을 만들어 보자

    • ()로 묶어주면 그룹이 된다.

()로 여러번 묶으면 nested group 처리도 가능하다.

 

2개의 케이스를 처리해보자

or(|)을 통해서 처리할 수 있다.

 

그룹을 언급해보자

 

 \0(일반적으로 전체 일치 텍스트), \1(그룹 1), \2(그룹 2) 등을 사용하여 캡처된 그룹을 참조할 수 있습니다. 예를 들어 텍스트 편집기에서 검색을 수행하고 정규식을 사용하여 두 개의 숫자를 교환할 때 "(\d+)-(\d+)"를 검색하고 "\2-\1"로 대체하여 두 번째 캡처된 숫자를 첫 번째로, 첫 번째 캡처된 숫자를 두 번째로 넣을 수 있습니다.

 

전방탐색 : 긍정형 (?=)

  • 검색 조건에는 포함되나 결과에는 포함되지 않는다
import re
p = re.compile(".+:")
m = p.search("http://google.com")
print(m.group()) # http:
import re
p = re.compile(".+(?=:)")
m = p.search("http://google.com")
print(m.group()) # http

전방탐색 : 부정형 (?!)

  • 검색 조건에 포함되지 않게 한다.
import re
p = re.compile(".*[.](?!bat$|exe$).*$", re.M)
m = p.findall("""
autoexec.exe
autoexec.bat
autoexec.jpg
""")
print(m) # ["autoexec.exe", "autoexec.jpg"]

Greedy와 Non-Greedy

greedy이면 최대한 긴 result를 만들고 non-greedy이면 가장 처음으로 match될 때 바로 리턴해준다.

반복되는 메타문자 뒤쪽에 물음표를 써준다

import re

input_string = "<html><head><title>"
print(re.match('<.*?>', input_string).group()) # <html>
print(re.match('<.*>', input_string).group()) # <html><head><title>

 

/{ }/g {}안에 넣을 부분

(Hi|Hello) : group1으로 지정 가능. 

(Hi|Hello)|(And): 그룹1, 그룹2

gr(e|a)y

따로 그룹을 만들고 싶지 않다면…

gr(?:e|a)y 처럼 하면 그룹이 안생긴다. 

 

2. In Python

내가 제일 궁금했던건 원하는 부분의 문자열만 리턴받을 수 있는지 였다. 

 

일단 기본

import re
p = re.compile(‘ab*’) # p라는 패턴 객체가 생긴다. 
m = p.match(주어진 string) # match 객체로 리턴한다.
p = re.compile(r'\\section')

처럼 r을 써서 raw string인 것을 알려줄 수 있다. 

 

패턴 객체를 사용하는 방법

1.match

match의 결과로 match객체 혹은 None을 리턴한다. match는 regex가 주어진 문자열의 부분이 아니라 전체여야 한다! 만약 부분부분 찾아줬으면 좋겠으면 search함수를 쓰자.

import re
p = re.compile(‘[a-z]+’) # p라는 패턴 객체가 생긴다. 
m = p.match('3 string') # match 객체로 리턴한다.
print(m) # None이 나온다.

2. Search

문자열 전체를 검색해서 일치하는 값이 있으면 match객체를 리턴한다. 처음 한개만 리턴해준다.

import re
p = re.compile(‘[a-z]+’) # p라는 패턴 객체가 생긴다. 
m = p.search('3 string') # match 객체로 리턴한다.
print(m) # string이 나온다.

3. Findall

일치하는걸 찾아서 리스트로 리턴

import re
p = re.compile(‘[a-z]+’) # p라는 패턴 객체가 생긴다. 
m = p.findall('life is too short') # match 객체로 리턴한다.
print(m) # ['life', 'is', 'too', 'short']

4. Finditer

iterator object에 담아준다. 

5. sub

A를 B로 바꿔준다! 파이썬에서는 1대1 대치밖에 안됐는데 regex를 쓰니 여러개를 한 단어로 바꿀 수 있어서 좋은것같다. 

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

 

Match 객체 쓰는법

p.match()를 하면 나오는 객체를 어떤 방식으로 쓰는지 알아보자  

  • group() : 매치된 문자열을 돌려준다.
  • start(): 매치된 문자열의 시작 위치를 돌려준다.
  • end() : 매치된 문자열의 끝 위치를 돌려준다.
  • span() : 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다.
import re
p = re.compile(‘[a-z]+’) # p라는 패턴 객체가 생긴다. 
m = p.match('python') # match 객체로 리턴한다.
print(m.group()) # python
print(m.start()) # 0
print(m.end()) # 6
print(m.span()) # (0, 6)

re.compile에 넣어줄 수 있는 compile option

  • re.dotall : dot문자가 줄바꿈도 포함하도록 하는 옵션이다!
import re
p = re.compile('a.b', re.DOTALL)
print(p.match('a\nb'))
  • re.ignorecase : 대소문자를 무시하게 해주는 옵션이다. 원래의 string을 소문자로 바꾸는게 아니라, match에서 확인할 때 무시한는 것이라서 결과는 대소문자가 보존되어서 나온다. 
import re
p = re.compile('[a-z]', re.I) # re.ignorecase 와 같다
print(p.match('python')) # p 
print(p.match('Python')) # P
print(p.match('PYTHON')) # P
  • re.multiline
import re
p = re.compile("^python\s\w+") # ^: 맨 처음, \s: 공백을 나타내는 문자, \w: word
data = """python one
life is too short
"""
print(p.findall(data)) # ['python one']
import re
p = re.compile("^python\s\w+", re.M) # ^: 맨 처음, \s: 공백을 나타내는 문자, \w: word
data = """python one
life is too short
python two
"""
print(p.findall(data)) # ['python one', 'python two']
  • re.verbose
  • 주석을 달 수 있는 기능! 문자열에 사용된 whitespace는 컴파일할 때 제거된다(단 [ ] 안에 사용한 whitespace는 제외). 그리고 줄 단위로 #기호를 사용하여 주석문을 작성할 수 있다.

 

In JavaScript

function validateGithubView(str){

  const re: RegExp = /https:\/\/github.com\/[\w\W]+\/[\w\W]+/

  return re.test(str)

}

 

In Python

 

Import re

P = re.compile(‘ab*’) # p라는 리턴 객체가 생긴다. 

m = p.match(주어진 string) # match 객체로 리턴한다. 

 

Match

Search

Findall: 일치하는걸 찾아서 리스트로 리턴

Finditer: iterator object에 담아준다. 

 

Match 객체의 사용

  • group() : 
  • start()
  • end()
  • span()

 

re.compile에 넣어줄 수 있는 compile option

  • re.dotall
  • re.ignorecase
  • re.multiline
  • re.verbose

/{ }/g {}안에 넣을 부분

 

apple: apple이 잡힌다. 

Hi|Hello: HI나 Hello중 match되는 것

(Hi|Hello) : group1으로 지정 가능. 

(Hi|Hello)|(And): 그룹1, 그룹2

gr(e|a)y

따로 그룹을 만들고 싶지 않다면…

gr(?:e|a)y 처럼 하면 그룹이 안생긴다. 

 

 

gr[a-f]y : gray, grby등 범위 안에 있는거

gr[^a-f]y 처럼 ^을 쓰면 반대 의미가 된다. 

 

 

TODO
re.split()

 

어떤 것들은 python함수로 더 쉽게 해결된다.

ex) array안에 있는 단어들 필터링하기

a = "tf tf t f"

my_deeplearning_dict = {
    "ml": "machine learning",
    "tf": "tensorflow",
}

for key,value in my_deeplearning_dict.items():
   a = (re.sub(key, value, a))
print(a)

3. 유용한 사이트

 

 

[출처]

https://regexr.com/5ml92

https://www.youtube.com/watch?v=dTDoTR0MXjU

https://www.youtube.com/watch?v=t3M6toIflyQ&t=723s

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함