-
#1 파이썬 정규 표현식 공부 (regular expression)컴퓨터/파이썬 2020. 5. 11. 22:33728x90반응형
string 의미 \d 숫자 [0-9] \D 숫자 아닌 것 [^0-9] \s [ \t\n\r\f\v ] \S [^\s] \w 문자+숫자
[a-zA-Z0-9]\W [^\w] [ ] 문자 클래스 . \n 제외한 모든 문자 매치
(a.b = a+모든+b)* 반복 : 0번 이상 무한 반복
(a*b = a + a*N + b)+ 반복 : 1번 이상 무한 반복
(a+b = a + a*N + b){m,n} 반복 : m~n번 반복
(a{2}b = a + aa + b)
{,2} = 0~2
{2, } = 2~무한? 반복 : {0, 1} 의미
(a?b = a + a(없어도 됨) + b)?P 하위 표현식 이름 붙히는 법
(?P<name>\w{3})\g 하위 표현식 group
a.sub("(\g<name>)", data)( 식 ) 하위 표현식에 넣는 방법 -> sub(\g<1>, g<2>) 식으로 사용 가능 (lambda x: x.group(n))
(19|20)\d{2} = 19xx or 20xx 문자를 캐치하는 법
\<H([1-5])\>.*?\<\/H\1\> = <H1></H1>과 같이 시작태그=끝태그 알맞게 끝났는지 체크
( 1~5까지를 하위표현식에 넣어, 각각 매치되는 태그로 끝내기. \1)
1. 주민번호 뒷자리 가리기
※ (\d{6})[-]\d{7} = 6자리-7자리, 앞자리를 유지하기 위해, (하위 표현식)에 넣음
import re # 주민번호 뒷자리 가리기 data = """ KUN : 800905-1049118 SON : 700905-1059119 KIM : 900905-2323222 """ pat = re.compile("(\d{6})[-]\d{7}") print(pat.sub("\g<1>-" + "*" * 7, data)) # KUN : 800905-******* ...
2. 전화번호 가리기
※ (?P<head>\d{3})-(\d{4})-(\d{4}) = 3개의 하위 표현식, 맨 앞자리를 head로 하위 표현식 이름을 지었음
import re # (010)-XXXX-XXXX 로 바꾸기 data = """ SEEK = 010-1234-5890 TEST = 010-4414-5142 TETT = 011-2421-1242 """ pat = re.compile("(?P<head>\d{3})-(\d{4})-(\d{4})") print(pat.sub("(\g<head>)-\g<2>-\g<3>", data)) # SEEK = (010)-1234-5890 ...
3. <H></H> 태그 안 문자 대문자화
※ \<H[1-5]\>(.*?)\<\/H[1-5]\> = 1개의 하위 표현식, <H></H> 안 문자만 대문자화
lambda 식을 사용해서 (.*?) 매치되는 문자 모두 대문자화, ("\g<1>".upper()은 작동 안 됨)
import re # H태그 안 문자들을 모두 대문자화 하기 data = """ <BODY> <H1>Welcome</H1> <p>this is p tag<></p> <H2>AbCCddeFGH</H2> <H3>test Word for</H3> <H4>la casa de papel</H3> <H5>svip coupon</H5> I have no tag, lonely </BODY> """ pat = re.compile("\<H[1-5]\>(.*?)\<\/H[1-5]\>") print(pat.sub(lambda x: x.group(1).upper(), data)) """ <h> 태그는 버린다 <BODY> WELCOME <p>this is p tag<>/p> """
4. 가장 긴 Palindrome regex로 찾기
\w + (.*) + \w = a ~ a 사이 글자(greedy)를 하위 표현식에 넣었음.
pattern.group() 을 통해 하위 표현식 불러옴 (re.search | TC = O(n))
import re def findlongestPalindromicSubstring(string): stack = set() for i, str in enumerate(string): new_string = string[i:] pattern = re.search(str + "(.*)" + str, new_string) if pattern: if is_palindrome(pattern.group()): print('pattern', pattern.group()) stack.add(pattern.group()) return max(stack, key=len) if len(string) > 1 else string def is_palindrome(str): return str == str[::-1] str = "abaabsvssvsaczcxbzccaabaczcaaa" print(findlongestPalindromicSubstring(str))
Regex Coach를 이용해서 바로바로 볼 수 있다.
혹은 온라인에서 실시간 (https://regexr.com/)
외전 : .* vs .*? (greedy vs Non-greedy)
eeeAiiZuuuuAoooZeeee 이 문자열을 각각의 regex를 사용해보면
A.*Z : AiiZuuuuAoooZ (1개만 매치) (끝까지 매칭되는 걸 찾음)
A.*?Z : AiiZ , AoooZ (2개 매치) (중간에 매치되면 끊고, 다른 것 찾음)
\<H([1-5])\>(.*?)\<\/H\1\> 에서
<H1>TEXT</H1>DDE</H1> 처음부터 앞 </H1>까지만 받음
(.*)으로 하면
<H1>~~</H1>~~</H1> 끝까지 매칭 모두 포함
728x90'컴퓨터 > 파이썬' 카테고리의 다른 글
#2 파이썬 여러가지 팁 (0) 2020.05.30 코로나 바이러스 현황을 파이썬 웹 request해서 GUI로 만들기 (0) 2020.05.08 파이썬 NetworkX 노드 색깔(color) (0) 2017.07.02