정규 표현식

쌍제이(JJVoiture)·2022년 3월 17일
0
post-custom-banner

Regular Expression

복잡한 문자열을 처리할 때 사용하는 기법.

Meta Character

원래 문자 뜻이 아닌 다른 용도로 사용하는 문자.

. ^ $ * + ? { } [ ] \ | ( )

문자 클래스 []

[abc]라면 이 정규식의 의미는 'a, b, c' 중 한 개의 문자와 매치를 의미한다.

[]안의 두 문자 사이에 하이픈 (-)을 사용하면 범위를 의미한다. (A-B -> From A to B)

예)
[a-e] == [abcde]
[0-8] == [012345678]

[a-zA-Z] : 모든 알파벳
[0-9]: 숫자

주의!!!!

문자클래스 안에서 ^를 사용하면 not이라는 의미를 갖는다.
[^0-9] : 숫자 말고 문자만 매치된다.

자주 사용하는 문자 클래스들
  • \d == [0-9]
  • \D == [^0-9]
  • \s : whitespace 문자와 매치 (==[ \t\n\r\f\v])와 동일한 표현, 맨 앞의 빈칸은 공백문자
  • \S : ==[^ \t\n\r\f\v]
  • \w == [a-zA-Z0-9_] 문자 + 숫자와 매치
  • \W == [^a-zA-Z0-9_] 문자 + 숫자가 아닌 것과 매치

Dot (.)

\n을 제외한 모든 문자와 매치된다.

예)
a.b: a와 b 사이에 어떠 ㄴ문자가 들어가도 모두 매치됨

O: aab, a0b
X: abc (X)

*문자 클래스 내에 dot이 있으면 모든 문자가 아닌 .로 인식된다.

반복 (*)

  • 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미

반복 (+)

*가 0번부터라면 +는 최소 1번 이상 반복될 때 쓰인다.

반복 ({m,n}, ?)

반복 m회 이상 n회 이하만 반복

{m,}: m회 이상
{,n}: n회 이하
{m}: 딱 m회 반복

?

b?

b가 있어도 되고 없어도 된다는 의미

|

ABC|DEF

ABC 또는 DEF

^

문자클래스[]에서와는 헷갈리지 말자!
^Life / Life is too short

--> O

^는 문자열의 맨 처음과 일치함을 의미한다.
multiline일 경우에는 각 줄의 문자열의 처음과 일치함을 의미한다.

$

short$ / Life is too short

--> O

$는 문자열의 맨 끝과 일치함을 의미한다.

* 문자열로 ^, $를 사용하고 싶다면 \를 앞에 붙여서 사용하도록 하자.

\A

^와 동일하지만 차이점으로는 multiline인 경우에도 전체 문자열의 처음하고만 매치된다.

\Z

$와 동일하지만, multiline인 경우에도 전체 문자열의 끝하고만 매치된다.

\b

단어 구분자로 쓰인다

>>> p = re.compile(r'\bclass\b')
>>> print(p.search('no class at all'))  
<re.Match object; span=(3, 8), match='class'>

이 때 단어 안에 문자열이 포함되어 있다면 whitespace로 구분된 단어가 아니므로 매치되지 않는다.

>>> print(p.search('the declassified algorithm'))
None

이 때 파이썬에서는 \b는 backspace를 의미하므로 단어 구분자로 쓰고 싶다면
r'\bclass\b'와 같은 형태로 사용하자. (raw string)

\B

\B와 반대.
단어의 앞 뒤에 whitespace가 하나라도 있으면 매치가 안 된다

grouping

문자열이 반복되는지 조사하는 정규식
()라는 메타 문자를 사용하자

(ABC)+

예를 들어 문자열에서 일부 문자열만 빼내고 싶은 부분만 ()로 grouping하는 식으로 사용할 수 있다.

>>> p = re.compile(r"(\w+)\s+\d+[-]\d+[-]\d+")
>>> m = p.search("park 010-1234-1234")
>>> print(m.group(1))
park

전방 탐색

  • 긍정형 전방 탐색((?=...)) - ... 에 해당되는 정규식과 매치되어야 하며 조건이 통과되어도 문자열이 소비되지 않는다.
  • 부정형 전방 탐색((?!...)) - ...에 해당되는 정규식과 매치되지 않아야 하며 조건이 통과되어도 문자열이 소비되지 않는다.
>>> p = re.compile(".+(?=:)")
>>> m = p.search("http://google.com")
>>> print(m.group())
http

Greedy vs Non-Greedy

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print(re.match('<.*>', s).span())
(0, 32)
>>> print(re.match('<.*>', s).group())
 <html><head><title>Title</title>

<html><head><title>Title</title>가 아니라 <html>까지만 소비하려면

?를 사용하자. <.*?>

출처
점프 투 파이썬: 07장 정규표현식

profile
안녕하세요. 중구난방 개발자 쌍제이입니다.
post-custom-banner

0개의 댓글