Python에서 읽기 쉽고 우아한 Regex 패턴을 작성하는 방법

Regex는 의심할 여지 없이 지금까지 발명된 가장 유용한 텍스트 처리 도구입니다. 텍스트에서 정확한 단어나 구가 아닌 패턴을 찾는 데 도움이 됩니다. 정규식 엔진도 눈에 띄게 빠릅니다.

그러나 어려운 부분은 패턴을 정의하는 것입니다. 숙련된 프로그래머는 이동 중에 정의할 수 있습니다. 그러나 대부분의 개발자는 문서를 검색하고 읽는 데 시간을 할애해야 합니다.

경험에 관계없이 모든 사람은 다른 사람이 정의한 패턴을 읽는 것이 어렵다는 것을 알게 됩니다.

이것이 PRegEx가 해결하는 문제입니다.

PRegEx는 정규식 패턴을 보다 우아하고 읽기 쉽게 만드는 Python 라이브러리입니다. 이제 cleaner python code에 대해 내가 가장 좋아하는 라이브러리 중 하나입니다.

PyPI 저장소에서 설치할 수 있습니다.

pip install pregex


사용 중인 경우Poetry instead of Virtualenv

poetry add pregex


더 읽기 쉬운 정규식 작성을 시작하십시오.



다음은 PRegEx가 얼마나 멋진지 파악하는 예입니다.

주소에서 (미국) 우편 번호를 추출해야 하는 것이 널리 퍼져 있습니다. 주소가 표준화되어 있으면 어렵지 않습니다. 그렇지 않으면 일부 영리한 기술을 사용하여 추출해야 합니다.

미국 우편 번호는 일반적으로 다섯 자리 숫자입니다. 또한 일부 우편번호는 하이픈으로 구분된 4자리 확장자를 가질 수 있습니다.

예를 들어 88310은 뉴 멕시코의 우편 번호입니다. 일부는 88310–7241과 같은 내선 번호가 있는 지리적 세그먼트도 사용하는 것을 선호합니다.

다음은 이러한 종류의 패턴을 찾기 위한 일반적인 접근 방식(re 모듈 사용)입니다.

import re

pattern = r"\d{5}(-\d{4})?"

address = "730 S White Sands Blvd, Alamogordo, NM 88310, United States"

zip_code = re.search(pattern, address).group()

print(zip_code)

# 88310


단계는 간단해 보일 수 있습니다. 하지만 초보 프로그래머에게 패턴을 어떻게 정의했는지 설명하려면 1시간 강의를 해야 한다.

저도 설명하지 않겠습니다. PREgEx가 있기 때문입니다. 다음은 PRegEx 버전입니다.

from pregex.classes import AnyDigit
from pregex.quantifiers import Exactly, Optional

pattern = Exactly(AnyDigit(), 5) + Optional("-" + Exactly(AnyDigit(), 4))

address1 = "730 S White Sands Blvd, Alamogordo, NM 88310, United States"
address2 = "730 S White Sands Blvd, Alamogordo, NM 88310-7421, United States"

pattern.get_matches(address1)
# ['88310']

pattern.get_matches(address2)
# ['88310-7421']


보시다시피 이 코드는 정의하고 이해하기 쉽습니다.

패턴에는 두 개의 세그먼트가 있습니다. 첫 번째 세그먼트는 정확히 5자리여야 하며 두 번째 세그먼트는 선택 사항입니다. 또한 사용 가능한 경우 두 번째 세그먼트에는 하이픈과 4개의 숫자가 있어야 합니다.

하위 모듈을 이해하여 더 흥미로운 정규식 패턴을 만듭니다.



여기에서 우리는 PRegEx 라이브러리의 몇 가지 하위 모듈인 클래스와 수량자를 사용했습니다. 'classes' 하위 모듈은 일치시킬 항목을 결정하고 수량자 하위 모듈은 수행할 반복 횟수를 지정하는 데 도움을 줍니다.

AnyButDigit과 같은 다른 클래스를 사용하여 숫자가 아닌 값을 일치시키거나 AnyLowercaseLetter를 소문자 문자열과 일치시킬 수 있습니다. 보다 복잡한 정규식 패턴을 생성하기 위해 OneOrMore, AtLeast, AtMost 또는 Indefinite와 같은 다른 수량자를 사용할 수도 있습니다.

더 흥미로운 경기가 있는 또 다른 예가 있습니다. 텍스트에서 이메일 주소를 찾아야 합니다. 간단합니다. 그러나 우리는 패턴을 일치시키는 것 외에도 이메일 주소의 도메인을 캡처하는 데에도 관심이 있습니다.

from pregex.classes import AnyButWhitespace
from pregex.groups import Capture
from pregex.quantifiers import OneOrMore, AtLeastAtMost


pattern = (
    OneOrMore(AnyButWhitespace())
    + "@"
    + Capture(
        OneOrMore(AnyButWhitespace()) + "." + AtLeastAtMost(AnyButWhitespace(), 2, 3)
    )
)

text = """My names is Alice. I live in Wonderland. You can mail me: [email protected]. 
In case if I couldn't reply, please main my friend the White Rabbit: [email protected].
But for more serious issues, you should main Tony Stark at [email protected].
"""

# Get everything you captured. 
pattern.get_captures(text)
# [('wonderland.com',), ('wonderland.com',), ('stark.org',)]

# Get all your matches. 
pattern.get_matches(text)
# ['[email protected]', '[email protected]', '[email protected]']


위의 예에서 'groups' 하위 모듈의 Capture 클래스를 사용했습니다. 이를 통해 매치 내에서 세그먼트를 수집할 수 있으므로 세그먼트를 추출하기 위해 사후 처리를 수행할 필요가 없습니다.

종종 필요한 또 다른 하위 모듈은 operator 모듈입니다. 패턴을 연결하거나 일련의 옵션 중 하나를 선택하는 데 도움이 됩니다.

다음은 위의 동일한 예제를 약간 수정한 버전입니다.

from pregex.classes import AnyButWhitespace
from pregex.groups import Capture
from pregex.operators import Either
from pregex.quantifiers import OneOrMore


pattern = (
    OneOrMore(AnyButWhitespace())
    + "@"
    + Capture(OneOrMore(AnyButWhitespace()) + Either(".com", ".org"))
)

text = """My names is Alice. I live in Wonderland. You can mail me: [email protected]. 
In case if I couldn't reply, please main my friend the White Rabbit: [email protected].
But for more serious issues, you should main Tony Stark at [email protected].
Please don't message [[email protected]](https://thuwarakesh.medium.com/subscribe)
"""

pattern.get_captures(text)
# [('wonderland.com',), ('wonderland.com',), ('stark.org',)]



위의 예에서는 최상위 도메인을 '.com' 또는 '.org'로 제한했습니다. 이 패턴을 구축하기 위해 연산자 하위 모듈의 'Either' 클래스를 사용했습니다. 보시다시피 최상위 도메인이 '.com'이나 '.org'가 아닌 '.err'이므로 [email protected]과 일치하지 않습니다.

마지막 생각들



정규식 정의는 숙련된 개발자에게 큰 작업이 아닐 수 있습니다. 그러나 그들에게도 누군가가 만든 패턴을 읽고 이해하는 것은 어렵다. 초보자에게는 두 가지 모두 어려울 수 있습니다.

게다가 정규식은 텍스트 마이닝을 위한 훌륭한 도구입니다. 모든 개발자 또는 데이터 과학자는 거의 확실하게 정규식 사용을 접하게 될 것입니다.

파이썬 프로그래머라면 PRegEx에서 복잡한 부분을 다룰 수 있습니다.


읽은 내용이 마음에 드셨나요? Consider subscribing to my email newsletter 이런 식으로 더 자주 게시하기 때문입니다.

읽어줘서 고마워, 친구! , 및 Medium에서 나에게 인사하세요.

좋은 웹페이지 즐겨찾기