본문 바로가기
조회 수 2187 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
(?iLmsux) 옵션 set 으로 하나 이상의 플래그를 RE에 명시할 수 있다.

** re.I/IGNORECASE 와 re.M/MULTILIN

>>> re.findall(r'(?i)yes', 'yes? Yes. YES!!') <------ 대소문자 무시하고 패턴매칭 후 list 리턴
['yes', 'Yes', 'YES']

>>> re.findall(r'(?i)th\w+', 'The quickest way is through this tunnel.') <--- 대소문자 무시. th이후 하나 이상의 문자들 매치
['The', 'through', 'this']

>>> str = """This line is the first,
... another line,
... that line, it's the best"""
>>> re.findall(r'(?i)(^th[\w ]+)', str) <---- 문자열 전체를 single 라인으로 간주. ^는 문자열 전체 최초만 매치
['This line is the first'] 
>>> re.findall(r'(?im)(^th[\w ]+)', str) <----------- using "multiline". ^는 각 행의 처음과 매치
['This line is the first', 'that line']


** re.S/DOTALL (이 플래그 명시시 .은 \n도 포함됨)

>>> re.findall(r'th.+', ''' <------- 문자열을 single 라인으로 간주하고 패턴매칭. dot(.)은 \n 포함안됨
... The first line
... the second line
... the third line
... ''')
['the second line', 'the third line']

해석: 위의 대상문자열은 아래와 같으며, dot(.)은 \n를 포함하지 않으므로 두개의 요소를 가진 list 리턴
"\nThe first line\nthe second line\nthe third line\nb"

아래와 같이 (?s)를 포함시킬 경우 dot(.)은 \n을 포함하게 되므로 하나의 요소를 가진 list 리턴

>>> re.findall(r'(?s)th.+', '''
... The first line
... the second line
... the third line
... ''')
['the second line\nthe third line\n']


** re.X/VERBOSE 플래그
: 패턴에 whitespace를 버림으로서 읽기 편하게 만든다. (단, backslash-escape로 명시가능) 또한 # 코멘트가 가능하다.

- 전화번호를 리스트로 리턴

import re
str = '(800) 555-1212'
mtc = re.search(r'''(?x) <------- whitespace (space, newline, ..) 무시되므로 여러 행 가능
\((\d{3})\) # area code <------ # 이후는 코멘트
[ ] # space <----- 공백이 무시되므로 [ ]로 했음
(\d{3}) # prefix
- # dash
(\d{4}) # endpoint number
''', str).groups()
print mtc
---- output ----
('800', '555', '1212')


** (?:...) notation
: 괄호()로 묶은 서브그룹을 저장하여 후에 사용할 필요가 없을 경우 패턴매칭에서 그룹핑으로만 사용

예) 도메인주소만 list로 출력하기

import re
str = 'http://google.com http://www.google.com http://code.google.com'
match_list = re.findall(r'''(?x)
http://
(?:\w+\.)* #
(\w+\.com)
''', str)
print match_list
---- output ----
['google.com', 'google.com', 'google.com']


** (?P<name>) and (?P=name) notations 
: 이 표기법은 \1, \2, .. \n 등의 매치된 문자열을 사용시 \n 대신 이름을 사용하게 해준다.

- 매치의 groupdict() 메소드를 사용해 dictionary로 리턴. key로 (?P<name>) 사용

>>> re.search(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})', '(800) 555-1212').groupdict()
{'areacode': '800', 'prefix': '555'}

- sub()을 사용해 바꾸시 사용시 \n 대신 이름을 이용

>>> re.sub(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})', '(\g<areacode>) \g<prefix>-xxxx', '(800) 555-1212')
'(800) 555-xxxx'

- 패턴 재사용시 이름을 이용

>>> bool(re.match(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?P<number>\d{4}) (?P=areacode)-(?P=prefix)-(?P=number) 1(?P=areacode)(?P=prefix)(?P=number)', '(800) 555-1212 800-555-1212 18005551212'))
True

위 코드를 (?x)를 사용해 읽기쉬게 만들면 아래와 같다.

print bool(re.match(r'''(?x)
  # match (800) 555-1212, save areacode, prefix, no.
  \((?P<areacode>\d{3})\)[ ](?P<prefix>\d{3})-(?P<number>\d{4})
  
  # space
  [ ]
  
  # match 800-555-1212
  (?P=areacode)-(?P=prefix)-(?P=number)
  
  # space
  [ ]
  
  # match 18005551212
  1(?P=areacode)(?P=prefix)(?P=number)
  
  ''', '(800) 555-1212 800-555-1212 18005551212'))
-------- output ------------
True


** 기타 (특수 문자 및 특수 ASCII 심볼)
: ASCII 와 RE 에서 사용된 동일한 심볼이 있을 경우 문제가 발생된다. 그러므로 RE에서 raw string 사용을 권장한다. 추가로 \w 와 \W 알파벳숫자 문자는 re.L/LOCALE 와 Unicode (re.U/UNICODE) 플래그의 영향을 받는다.

예를 들면, \b는 ASCII 문자에서 백스페이스를 의미하지만 RE에서는 워드 바운더리를 의미한다. RE 컴파일러는 \b를 백스페이스 대신 두개의 문자 \ 와 b 로 인식한다. ASCII 문자의 특수문자로 인식하기 위해서는 \를 escape해야한다. 즉, \\b 라고 명시해야 한다.

>>> re.match('\bblow', 'blow').group() <------- \b를 ASCII 특수문자 백스페이스로 인식. match 안됨
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

>>> re.match('\\bblow', 'blow').group() <-------- \\b를 RE 특수문자 워드바운더리로 인식. match 됨
'blow'

특수문자가 많아지면 복잡해지므로 raw string 사용해 ASCII와 RE에서 동일한 특수문자는 RE로 인식하도록 한다.

>>> re.match(r'\bblow', 'blow').group()
'blow'

참고. \d의 경우 raw string 사용유무의 상관없이 RE 특수문자로 인식한다. 이유는 \d는 동일한 ASCII 특수문자가 없기 때문이다. raw string 사용은 ASCII와 RE에서 동일한 (다른 의미의)특수문자를 위한 것이다.


** RE 예1

- 아래와 같은 who 출력을 RE사용해 user, teletype, date/time을 요소로 하는 리스트로 저장
(힌트: 공백이 2개 이상인 것을 분리문자로 사용)

$ cat whodata.txt
hyun     console  Mar 25 07:46 
hyun     ttys000  Mar 25 08:42 
hyun     ttys001  Mar 25 07:47 
hyun     ttys002  Mar 25 07:54 
hyun     ttys003  Mar 25 07:55 
hyun     ttys004  Mar 25 08:51 
hyun     ttys005  Mar 25 08:51 

import re
f = open('whodata.txt', 'r')
for eachline in f:
print re.split(r'\s\s+', eachline.strip())
f.close()
-------- output ------
['hyun', 'console', 'Mar 25 07:46']
['hyun', 'ttys000', 'Mar 25 08:42']
['hyun', 'ttys001', 'Mar 25 07:47']
['hyun', 'ttys002', 'Mar 25 07:54']
['hyun', 'ttys003', 'Mar 25 07:55']
['hyun', 'ttys004', 'Mar 25 08:51']
['hyun', 'ttys005', 'Mar 25 08:51']

- 탭으로 구분된 경우 \t 추가
print re.split(r'\s\s+|\t', eachline.rstrip())

- who 명령을 바로 사용해서 RE를 할 경우
import re
import os
f = os.popen('who', 'r')
for eachline in f:
print re.split(r'\s\s+', eachline.rstrip())
f.close()

** RE 예2
: 아래와 같이 ps 출력에 각 항목을 list로 리턴

$ ps a
  PID   TT  STAT      TIME COMMAND
 6677 s000  Ss     0:00.03 login -pf hyun
 6678 s000  S      0:00.04 -bash

import re
import os

f = os.popen('ps a', 'r')
for eachline in f:
match_list = re.findall(r'''(?x) # raw string and x,m flag
(\d+)
[ ]
(s\d+)
\s\s+
([\w\+-]+)
\s\s+
(\d:\d{2}\.\d{2})
[ ]
(.*)
''', eachline.rstrip())
print match_list
f.close()
--------- output ----------
[]
[('6677', 's000', 'Ss', '0:00.03', 'login -pf hyun')]
[('6678', 's000', 'S+', '0:00.04', '-bash')]


Title
List of Articles
번호 제목 글쓴이 날짜 조회 수
58 Python 2.7 in CentOS with no issue (setuptools, pip, virtualenv) Hojung 2014.08.31 3361
57 GUI 기본 file Hojung 2013.04.06 5289
56 Gmail SMTPx2, POP, IMAP Script Hojung 2013.04.06 3352
55 E-Mail 작성 및 발송 스크립트 Hojung 2013.04.06 3656
54 Interactive IMAP4 Script Hojung 2013.04.06 3025
53 SMTP and POP3 Script Hojung 2013.04.06 2155
52 Interactive POP3 Script file Hojung 2013.04.06 2697
51 Interactive SMTP Script Hojung 2013.04.06 2157
50 FTP Download Script Hojung 2013.04.06 7010
49 SocketServer 모듈을 사용해 TCP Server/Client 작성 Hojung 2013.04.06 4815
48 Network Programming - socket() 모듈을 사용해 UDP Server, client 생성 Hojung 2013.04.06 4777
47 Network Programming - socket() 모듈을 사용해 TCP Server, client 생성 Hojung 2013.04.06 14650
46 brew install python on Mac OS X + pyqt, lxml and spynner Hojung 2013.03.29 4944
45 Regular Expression (search vs match 그리고 Greediness) file Hojung 2013.03.26 2375
» Regular Expression - Extension Notations (?...) Hojung 2013.03.26 2187
43 Regular Expression (문자열을 RE를 이용 list 리턴) - split() Hojung 2013.03.26 3100
42 Regular Expression (찾기 및 바꾸기) - sub() and subn() Hojung 2013.03.26 2421
41 Regular Expression (찾기) - findall() and finditer() Hojung 2013.03.26 3309
40 Regular Expression (matching vs searching) Hojung 2013.03.23 8463
39 How to install pip, spynner, macports and py-pyqt4 Hojung 2013.03.22 3510
Board Pagination ‹ Prev 1 2 3 Next ›
/ 3

Designed by sketchbooks.co.kr / sketchbook5 board skin

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5