티스토리 뷰

Back-ends/python

정규식 (Regular Expression)

이주성 2018. 12. 30. 18:20
Regular-Expression-2

정규식 (Regular Expression)

Table Of Contents

  1. 반복 메타 문자
  2. Match (문자열 매치하기)
  3. Search (부분적으로 매치하기)
  4. substitute (대치)
  5. 최소 매칭
  6. 정규식 객체 사용하기
  7. SAMPLE (HTTP URL 매칭)

반복 메타 문자

반복 메타 문자 의미
* 0회이상 반복 ca*는 ct,cat, caaaat등과 매치
+ 1회이상 반복 ca+는 cat, caaaat등과 매치된다
? 0회 혹은 1회 ca?t는 ct, cat와 매치된다
{m} m회 반복 ca{2}는 caa와 매치된다.
{m,n} m회부터 n회까지 반복 ca{2,4}는 caat, caaat, caaaat와 매치

매칭 메타 문자

메타문자 의미
. 줄바꿈 문자를 제외한 모든 문자와 매치된다. re.DOTALL모드로 사용하면 줄바꿈문자도 매치가능
^ 1.문자열의 시작과 매치된다. re.MULTILINE모드에서는 각라인의 시작과 매치된다. 2.[]메타기호 안에서는 반대의 문자열을 취한다. [^5]는 5가아닌 문자이다.
$ 1.문자열의 마지막과 매치된다. 2.[]메타 기호안에서는 메타 기호로 사용되지 않고 순수한 $문자로 매치된다.
[] 문자 집합을 나타낸다.[abc]는 a, b, c중 한 문자를 의미한다. [a-c]와 같이 쓸수 있다. -는 범위를 나타낸다.[a-zA-Z0-9]는 영문자 숫자를 의미한다.
| a|b는 a 또는 b의 의미이다
() 정규식을 그룹으로 묶는다.
  • c.t는 cat, cbt, cct등과 매치된다.
  • ^cat는 'cats and dogs'과 매치되지만, 'dogs and cats'와는 매치되지 않는다.
  • c[^a]t는 cbt,cct, cdt등과 매치되지만, cat와는 매치되지 않는다.
  • cat$는 'dogs and cats'와는 매치되지 않지만, 'a dot and a cat'와는 매치된다.
  • c[abc]는 cat, cbt, cct와 매치된다.
  • ca|bt는 ca, bt와 매치된다.

이스케이프 기호

분야 설명
\ 역슬래쉬 문자 자체를 의미한다.
\d 모든 숫자와 매치한다.[0-9]
\D 숫자가 아닌 문자와 매치된다.[^0-9]
\s 화이트 스페이스 문자와 매치된다.[\t\n\r\f\v]
\S 화이트 스페이스 문자가 아닌것과 매치된다.[^\t\n\r\f\v]
\w 숫자 또는 문자와 매치된다.[a-zA-Z0-9]
\W 숫자 또는 문자가 아닌 것과 매칭된다.[^a-zA-Z0-9]
\b 단어의 경계를 나타낸다. 단어는 영문자 혹은 숫자의 연속문자열로 가정한다.
\B \b의 반대로 단어의 경계가 아님을 나타낸다.

Match (문자열 매치하기)

>>> import re
>>> m = re.match('[0-9]', '1234')
>>> m.group()
'1'
>>> m = re.match('[0-9]+', '1234')
>>> m.group()
'1234'
>>> m = re.match('[0-9]+', '1234 ') // 뒤에 공백도 매치한다.
>>> m.group()

Search(부분적으로 매치)

>>> re.search('\d+', '   1034a ').group()
'1034'

substitute (대치)

정규식으로 찾은 단어를 다른 단어로 대치하는 것이다. XML의 숫자, 를 숫자, 로 어떻게 바꿀까? 아래 코드처럼 하면 된다. 간단히 설명하자면, 패턴의 (\d+,\d+) 이 837,773이되고, \1 은 group(1) 즉 837,773이 된다.

>>> str = '<tr><td>셋탑 수 (UNIQUE)  </td><td>837,773</td></tr>'
>>> re.sub(r'<td>(\d+,\d+)', r'<td style="text-align: right;">\1', str)
'<tr><td>셋탑 수 (UNIQUE)  </td><td style="text-align: right;">837,773</td></tr>'

비슷한 예로 아래처럼 함수명을 바꾸는 코드가 있는데, 여기서 \1 은 myfunc이다.

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

JAVA 에선 대치를 어떻게 하는걸까? 예를 들어서, 10,000원 에서 컴마를 제거하여 10000원 으로 만들고 싶으면 어떻게? 아래 JAVA 코드처럼 하면 된다. replaceAll에서도 $1(group(1)) 을 쓸수있다니. 난 몰랐었다ㅠ

 String str = ",20200325031326.702^CTPL46_muid|{EEC79781-DFE3-4060-A20A-05500F79C11C} HD일반 10,000원";
 System.out.println (str.replaceAll(",([0-9]00)", "$1"));
 결과물
 ,20200325031326.702^CTPL46_muid|{EEC79781-DFE3-4060-A20A-05500F79C11C} HD일반 10000

최소 매칭

메타문자 *,+,?는 가능하면 많은 문자들을 포함시키려고 노력한다. 이것을 탐욕적인 매칭(Greedy Matchin)이라고 한다.

>>> re.search(r'href="(.*)"', '<a href="index.html">HERE</a><font size=10>').group(1)
'index.html">HERE</a><font size="10'
>>> re.search(r'href="(.*?)"', '<a href="index.html">HERE</a><font size=10>').group(1)
'index.html'
기호 의미
*? *와 같으나 문자열을 최소로 매칭한다.
+? +와 같으나 문자열을 최소로 매칭한다.
?? ?와 같으나 문자열을 최소로 매칭한다.
{m,n}? {m,n}과 같으나 문자열을 최소로 매칭한다.

정규식 객체 사용하기

>>> p = re.compile(r'([_a-zA-Z]\w*)\s*=\s*(\d+)')
>>> m = p.match('a = 123')
>>> m.groups()
['a', '123']
>>> m.group(1)
'a'

HTTP URL 매칭

#!/usr/bin/python
import re

if __name__ == '__main__':
    with open("log.txt") as f:
        content = f.readlines()
    dicts = {}
    contents = ''
    for line in content:
        contents += line

    regex = re.compile(r'impression=\W+(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)]\W+')
    match_obj = regex.search(contents)
    for url in match_obj.groups():
        if dicts.has_key(url):
            print ('URL duplicated!!! = {}'.format(url))
        else:
            dicts[url] = 1

    print(match_obj.groups())

'Back-ends > python' 카테고리의 다른 글

Python 가상환경  (0) 2018.09.12
PATH 설정 (python)  (0) 2017.12.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함