๊ฐœ์š”

์ง€๊ธˆ๊นŒ์ง€๋Š” ๊ฐ„๋‹จํ•œ ์ •๊ทœ์‹์„ ์‚ดํŽด ๋ณด์•˜์ง€๋งŒ, ์‹ค์ œ๋กœ ์กด์žฌํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฌธ์ž์—ด์—์„œ ์ •๋ณด๋ฅผ ๋ฝ‘์•„๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€์ ์ธ ์˜ต์…˜์ด ํ•„์š”ํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‡ผํ•‘๋ชฐ์˜ ์ƒํ’ˆ ๋ฆฌ๋ทฐ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์ ์ธ ๋‹จ์–ด๋ฅผ ๋ฝ‘์•„๋‚ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ฆฌ๋ทฐ๋Š” ๋ฌธ์ž์—ด์€ ๋งž์ง€๋งŒ, ์ „์ฒด์ ์œผ๋กœ ๋ณด์•˜์„ ๋•Œ ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž(\n)๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค. ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž(\n)๋Š” ์ด์ „์— ๋ฐฐ์šด ๋ฌธ์ž์—ด์—์„œ ๋งค์น˜๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ์–ด๋–ค ๋ฌธ์ž์—ด์ด๋ƒ์— ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ๋‹ฌ๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ์ ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •๊ทœ์‹์„ ์ปดํŒŒ์ผํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์†Œ๊ฐœํ•œ๋‹ค.

optiondescribtion
DOTALL(S)๋ฉ”ํƒ€๋ฌธ์ž . ๊ฐ€ ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ๋ฌธ์ž์™€ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
IGNORECASE(I)๋Œ€์†Œ๋ฌธ์ž์— ๊ด€๊ณ„์—†์ด ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
MULTILINE(M)์—ฌ๋Ÿฌ์ค„๊ณผ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. (^, $ ๋ฉ”ํƒ€๋ฌธ์ž์˜ ์‚ฌ์šฉ๊ณผ ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ์˜ต์…˜์ด๋‹ค)
VERBOSE(X)verbose ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. (์ •๊ทœ์‹์„ ๋ณด๊ธฐ ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค์ˆ˜ ์žˆ๊ณ  ์ฃผ์„๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค.)

์˜ต์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” re.DOTALL์ฒ˜๋Ÿผ ์ „์ฒด ์˜ต์…˜ ์ด๋ฆ„์„ ์จ๋„ ๋˜๊ณ  re.S์ฒ˜๋Ÿผ ์•ฝ์–ด๋ฅผ ์จ๋„ ๋œ๋‹ค.

DOTALL(S)

๋ฉ”ํƒ€๋ฌธ์ž . ๊ฐ€ ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ๋ฌธ์ž์™€ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

. ๋ฉ”ํƒ€ ๋ฌธ์ž๋Š” ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž(\n)๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋ฌธ์ž์™€ ๋งค์น˜๋˜๋Š” ๊ทœ์น™์ด ์žˆ๋‹ค. ๋งŒ์•ฝ \n ๋ฌธ์ž๋„ ํฌํ•จํ•˜์—ฌ ๋งค์น˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด re.DOTALL ๋˜๋Š” re.S ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์ •๊ทœ์‹์„ ์ปดํŒŒ์ผํ•˜๋ฉด ๋œ๋‹ค.

>>> import re
>>> p = re.compile('a.b')
>>> m = p.match('a\nb')
>>> print(m)
None

์œ„์˜ ์˜ˆ๋ฅผ ๋ณด๋ฉด, ์ปดํŒŒ์ผ ์˜ต์…˜์„ ์ฃผ์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ฉ”ํƒ€๋ฌธ์ž .๋Š” ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž(\n)์™€ ๋งค์น˜๋˜์ง€ ์•Š์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

>>> p = re.compile('a.b', re.DOTALL)
>>> m = p.match('a\nb')
>>> print(m)
<_sre.SRE_Match object at 0x01FCF3D8>

์ด๋ฒˆ์—๋Š” ์˜ต์…˜์„ ์ค€ ๊ฒฝ์šฐ์ด๋‹ค. ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž๋„ ํฌํ•จํ•˜์—ฌ ๊ฒฐ๊ณผ์— ๋ฐ˜์˜ํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋ณดํ†ต re.DOTALL ์˜ต์…˜์€ ์—ฌ๋Ÿฌ ์ค„๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฌธ์ž์—ด์—์„œ \n์— ์ƒ๊ด€์—†์ด ๊ฒ€์ƒ‰ํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

IGNORECASE, I

๋Œ€์†Œ๋ฌธ์ž์— ๊ด€๊ณ„์—†์ด ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

re.IGNORECASE ๋˜๋Š” re.I ์˜ต์…˜์€ ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ณ„ ์—†์ด ๋งค์น˜๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ๋ณด์ž.

>>> p = re.compile('[a-z]', re.I)
>>> p.match('python')
<_sre.SRE_Match object at 0x01FCFA30>
>>> p.match('Python')
<_sre.SRE_Match object at 0x01FCFA68>
>>> p.match('PYTHON')
<_sre.SRE_Match object at 0x01FCF9F8>

[a-z] ์ •๊ทœ์‹์€ ์†Œ๋ฌธ์ž๋งŒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ re.I ์˜ต์…˜์œผ๋กœ ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ณ„ ์—†์ด ๋งค์น˜๋œ๋‹ค.

MULTILINE, M

์—ฌ๋Ÿฌ์ค„๊ณผ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

re.MULTILINE ๋˜๋Š” re.M ์˜ต์…˜์€ ๋‹ค์Œ ๊ธ€์— ์„ค๋ช…ํ•  ๋ฉ”ํƒ€ ๋ฌธ์ž์ธ ^, $์™€ ์—ฐ๊ด€๋œ ์˜ต์…˜์ด๋‹ค. ์ด ๋ฉ”ํƒ€ ๋ฌธ์ž์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด ^๋Š” ๋ฌธ์ž์—ด์˜ ์ฒ˜์Œ์„ ์˜๋ฏธํ•˜๊ณ , $๋Š” ๋ฌธ์ž์—ด์˜ ๋งˆ์ง€๋ง‰์„ ์˜๋ฏธํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ •๊ทœ์‹์ด ^python์ธ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด์˜ ์ฒ˜์Œ์€ ํ•ญ์ƒ python์œผ๋กœ ์‹œ์ž‘ํ•ด์•ผ ๋งค์น˜๋˜๊ณ , ๋งŒ์•ฝ ์ •๊ทœ์‹์ด python$์ด๋ผ๋ฉด ๋ฌธ์ž์—ด์˜ ๋งˆ์ง€๋ง‰์€ ํ•ญ์ƒ python์œผ๋กœ ๋๋‚˜์•ผ ๋งค์น˜๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

import re
p = re.compile("^python\s\w+")
 
data = """python one
life is too short
python two
you need python
python three"""
 
print(p.findall(data))
['python one']

์ •๊ทœ์‹ ^python\s\w+์€ python์ด๋ผ๋Š” ๋ฌธ์ž์—ด๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๊ทธ ๋’ค์— whitespace, ๊ทธ ๋’ค์— ๋‹จ์–ด๊ฐ€ ์™€์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ๊ฒ€์ƒ‰ํ•  ๋ฌธ์ž์—ด data๋Š” ์—ฌ๋Ÿฌ ์ค„๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ^ ๋ฉ”ํƒ€ ๋ฌธ์ž์— ์˜ํ•ด python์ด๋ผ๋Š” ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•œ ์ฒซ ๋ฒˆ์งธ ์ค„๋งŒ ๋งค์น˜๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋Š” ํ•ด๋‹น ๋ฌธ์ž์—ด์˜ ์ฒ˜์Œ์— ์กฐ๊ฑด์ด ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ณ , ๋ผ์ธ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์ฒ˜์Œ์ธ ๊ฒฝ์šฐ๋ฅผ ๋œปํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์ด re.MULTILINE ๋˜๋Š” re.M์ด๋‹ค.

import re
p = re.compile("^python\s\w+", re.MULTILINE)
 
data = """python one
life is too short
python two
you need python
python three"""
 
print(p.findall(data))
['python one', 'python two', 'python three']

re.MULTILINE ์˜ต์…˜์œผ๋กœ ์ธํ•ด ^ ๋ฉ”ํƒ€ ๋ฌธ์ž๊ฐ€ ๋ฌธ์ž์—ด ์ „์ฒด๊ฐ€ ์•„๋‹Œ ๊ฐ ์ค„์˜ ์ฒ˜์Œ์ด๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–๊ฒŒ ๋˜์—ˆ๋‹ค. ์ฆ‰, re.MULTILINE ์˜ต์…˜์€ ^, $ ๋ฉ”ํƒ€ ๋ฌธ์ž๋ฅผ ๋ฌธ์ž์—ด์˜ ๊ฐ ์ค„๋งˆ๋‹ค ์ ์šฉํ•ด ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

VERBOSE(X)

verbose ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

๊ณ ๋งˆ์šด ์˜ต์…˜์ด๋‹ค. ์‚ฌ์‹ค ์ •๊ทœ์‹์€ ์‚ฌ์šฉํ•˜๊ธฐ ๊นŒ๋‹ค๋กญ๋‹ค. ์ •๊ทœ์‹์€ ๋งˆ์น˜ ์‹œ์™€ ๊ฐ™์ด ํ•จ์ถ•์ ์ธ ๋‹จ์–ด๋“ค์˜ ์ง‘ํ•ฉ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ „๋ฌธ๊ฐ€๋“ค์ด ๋งŒ๋“ค์–ด ๋†“์€ ์ •๊ทœ์‹์„ ๋ณด๋ฉด ์ •๋ง ์„ฌ์„ธํ•˜๊ฒŒ ๋‹ค๋ค„์„œ ํ•ด์„ํ•ด์•ผ ํ•œ๋‹ค. ์ข€ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์—†์„๊นŒ? ์ด๋ ‡๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ์ •๊ทœ์‹์„ ์ฃผ์„ ๋˜๋Š” ์ค„ ๋‹จ์œ„๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์–ผ๋งˆ๋‚˜ ๋ณด๊ธฐ ์ข‹๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šธ๊นŒ? ์ด๋Ÿฌํ•œ ์š•๊ตฌ๋ฅผ ํ•ด์†Œํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ re.VERBOSE ๋˜๋Š” re.X ์˜ต์…˜์ด๋‹ค.

charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')
charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

์ฒซ ๋ฒˆ์งธ์™€ ๋‘ ๋ฒˆ์งธ ์˜ˆ๋ฅผ ๋น„๊ตํ•ด ๋ณด๋ฉด ์ปดํŒŒ์ผ๋œ ํŒจํ„ด ๊ฐ์ฒด์ธ charref๋Š” ๋ชจ๋‘ ๋™์ผํ•œ ์—ญํ• ์„ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ •๊ทœ์‹์ด ๋ณต์žกํ•  ๊ฒฝ์šฐ ๋‘ ๋ฒˆ์งธ์ฒ˜๋Ÿผ ์ฃผ์„์„ ์ ๊ณ  ์—ฌ๋Ÿฌ ์ค„๋กœ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

re.VERBOSE ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด์— ์‚ฌ์šฉ๋œ whitespace๋Š” ์ปดํŒŒ์ผํ•  ๋•Œ ์ œ๊ฑฐ๋œ๋‹ค(๋‹จ [ ] ์•ˆ์— ์‚ฌ์šฉํ•œ whitespace๋Š” ์ œ์™ธ). ๊ทธ๋ฆฌ๊ณ  ์ค„ ๋‹จ์œ„๋กœ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์„๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Reference