티스토리 뷰
이 글은 크게 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://www.youtube.com/watch?v=dTDoTR0MXjU
https://www.youtube.com/watch?v=t3M6toIflyQ&t=723s