Python - 여러 줄의 텍스트 블록과 일치하는 정규식

Salman Mehmood 2023년10월8일
  1. 여러 줄 문자열과 일치하도록 정규식을 작성하는 이유
  2. 여러 줄 문자열을 일치시키는 가능한 솔루션
Python - 여러 줄의 텍스트 블록과 일치하는 정규식

이 문서에서는 여러 줄 문자열에서 특정 패턴을 검색하는 방법에 대해 설명합니다. 이 솔루션은 알려진 패턴과 알려지지 않은 패턴에 대한 여러 접근 방식을 절충하고 일치 패턴이 작동하는 방식을 설명합니다.

여러 줄 문자열과 일치하도록 정규식을 작성하는 이유

다음과 같은 텍스트 블록이 있다고 가정합니다.

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

위에 주어진 텍스트 블록에서 시작 텍스트를 찾아야 하며 텍스트는 아래 몇 줄에 표시됩니다. \n은 개행을 상징하며 리터럴 텍스트가 아니라는 점에 유의해야 합니다.

요약하자면, 우리는 텍스트 사이에 올 수 있는 빈 줄을 무시하고 여러 줄에 걸쳐 텍스트를 찾고 일치시키기를 원합니다. 위에서 언급한 텍스트의 경우 단일 정규식 쿼리에서 Any compilation body.... 줄과 IBM first used the term.... 줄을 반환해야 합니다.

여러 줄 문자열을 일치시키는 가능한 솔루션

이 특정 문제에 대한 솔루션을 논의하기 전에 regex(정규식) API의 다양한 측면, 특히 솔루션 전체에서 자주 사용되는 측면을 이해하는 것이 중요합니다.

따라서 re.compile()부터 시작하겠습니다.

파이썬 re.compile() 메서드

re.compile() は正規表現パターンを正規表現オブジェクトにコンパイルし、match()search()、および他の説明されたメソッドで一致させるために使用できるようにします。

컴파일되지 않은 패턴에 비해 re.compile()의 장점 중 하나는 재사용성입니다. 컴파일되지 않은 각 패턴에 대해 새 문자열을 선언하는 대신 컴파일된 식을 여러 번 사용할 수 있습니다.

import re as regex

pattern = regex.compile(".+World")
print(pattern.match("Hello World!"))
print(pattern.search("Hello World!"))

출력:

<re.Match object; span=(0, 11), match='Hello World'>
<re.Match object; span=(0, 11), match='Hello World'>

파이썬 re.search() 메서드

re.search()는 문자열에서 일치 항목을 검색하고 일치 항목이 발견되면 Match 객체를 반환합니다. 여러 일치 항목이 있는 경우 첫 번째 인스턴스를 반환합니다.

또한 re.compile()을 사용하지 않고 직접 사용할 수도 있습니다. 쿼리가 하나만 필요한 경우에 적용할 수 있습니다.

import re as regex

print(regex.search(".+World", "Hello World!"))

출력:

<re.Match object; span=(0, 11), match='Hello World'>

파이썬 re.finditer() 메서드

re.finditer()는 문자열 내의 패턴과 일치하고 모든 겹치지 않는 일치에 대해 Match 객체를 전달하는 반복자를 반환합니다.

그런 다음 반복자를 사용하여 일치 항목을 반복하고 필요한 작업을 수행할 수 있습니다. 일치 항목은 문자열의 왼쪽에서 오른쪽으로 찾은 방식으로 정렬됩니다.

import re as regex

matches = regex.finditer(r"[aeoui]", "vowel letters")
for match in matches:
    print(match)

출력:

<re.Match object; span=(1, 2), match='o'>
<re.Match object; span=(3, 4), match='e'>
<re.Match object; span=(7, 8), match='e'>
<re.Match object; span=(10, 11), match='e'>

파이썬 re.findall() 메서드

’re.findall()‘은 문자열에서 패턴의 겹치지 않는 모든 일치 항목의 목록 또는 튜플을 반환합니다. 문자열은 왼쪽에서 오른쪽으로 스캔됩니다. 그리고 일치 항목은 검색된 순서대로 반환됩니다.

import re as regex

# Find all capital words
string = ",,21312414.ABCDEFGw#########"
print(regex.findall(r"[A-Z]+", string))

출력:

['ABCDEFG']

파이썬 re.MULTILINE 방법

re.MULTILINE의 중요한 이점은 ^가 문자열의 시작 부분이 아니라 모든 줄의 시작 부분에서 패턴을 검색할 수 있다는 점입니다.

파이썬 정규식 기호

Regex 기호는 복잡한 방식으로 사용될 때 매우 혼란스러울 수 있습니다. 다음은 이러한 기호의 기본 개념을 더 잘 이해하는 데 도움이 되도록 솔루션에 사용되는 일부 기호입니다.

  • ^ 줄의 시작 위치를 주장
  • String 문자 그대로 "String" 문자(대소문자 구분)와 일치합니다.
  • . 모든 문자와 일치(줄 종료에 사용되는 기호 제외)
  • +는 가능한 한 자주 이전에 주어진 토큰과 일치합니다.
  • \n은 개행 문자와 일치합니다.
  • \r은 (CR) 캐리지 리턴 기호와 일치합니다.
  • ? 0-1번 사이의 이전 토큰과 일치
  • +? 1에서 무한 시간 사이의 이전 토큰과 가능한 한 적게 일치합니다.
  • a-zaz 사이 범위의 단일 문자와 일치합니다(대소문자 구분).

Python에서 re.compile()을 사용하여 여러 줄의 텍스트 블록 일치

다른 패턴을 사용하여 이해합시다.

패턴 1: 알려진 패턴에 re.search() 사용

예제 코드:

import re as regex

multiline_string = "Regular\nExpression"
print(regex.search(r"^Expression", multiline_string, regex.MULTILINE))

출력:

<re.Match object; span=(8, 18), match='Expression'>

위의 식은 먼저 줄의 시작 부분에서 위치를 확인한 다음(^로 인해) "Expression"의 정확한 항목을 검색합니다.

MULTILINE 플래그를 사용하면 각 줄이 "Expression"의 발생을 확인하는 것이 아니라 첫 번째 줄만이 확인됩니다.

패턴 2: 알 수 없는 패턴에 re.search() 사용

예제 코드:

import re as regex

data = """Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.
"""

result = regex.compile(r"^(.+)(?:\n|\r\n)+((?:(?:\n|\r\n?).+)+)", regex.MULTILINE)

print(result.search(data)[0].replace("\n", ""))

출력:

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

정규 표현식은 더 나은 가독성을 위해 더 작은 청크로 분해하고 단순화할 수 있습니다.

첫 번째 캡처링 그룹 (.+)에서 각 문자는 줄에서 일치합니다(줄 종결자에 해당하는 기호는 제외). 이 프로세스는 가능한 한 자주 수행됩니다.

그런 다음 비캡처 그룹 (?:\n|\r\n)에서 줄 종결자만 또는 줄 종결자와 캐리지 리턴이 가능한 한 많이 일치합니다.

두 번째 캡처링 그룹 ((?:(?:\n|\r\n?).+)+)은 캡처링하지 않는 그룹 ((?:(?:\n|\r\n?).+)+) 개행 문자 또는 개행 문자와 캐리지 리턴이 최대 한 번 일치합니다.

줄 종결자를 제외하고 캡처하지 않는 그룹 외부의 모든 문자가 일치합니다. 이 절차는 가능한 한 여러 번 수행됩니다.

패턴 3: 알 수 없는 패턴에 re.finditer() 사용

예제 코드:

import re as regex

data = """Regex In Python

Regex is a feature available in all programming languages used to find patterns in text or data.
"""

query = regex.compile(r"^(.+?)\n([\a-z]+)", regex.MULTILINE)

for match in query.finditer(data):
    topic, content = match.groups()
    print("Topic:", topic)
    print("Content:", content)

출력:

Topic: Regex In Python
Content: 
Regex is a feature available in all programming languages used to find patterns in text or data.

위 식은 다음과 같이 설명할 수 있습니다.

첫 번째 캡처링 그룹 (.+?)에서 모든 문자는 가능한 한 적게 일치합니다(이전과 같이 줄 종결자 제외). 그런 다음 단일 개행 문자 \n이 일치합니다.

줄 바꿈 문자를 일치시킨 후 두 번째 캡처링 그룹 (\n[a-z ]+)에서 다음 작업이 수행됩니다. 먼저 개행 문자가 일치되고 a-z 사이의 문자가 가능한 한 많이 일치합니다.

Python에서 re.findall()을 사용하여 여러 줄 텍스트 블록 일치

예제 코드:

import re as regex

data = """When working with regular expressions, the sub() function of the re library is an invaluable tool.

the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found.
"""

query = regex.findall("([^\n\r]+)[\n\r]([a-z \n\r]+)", data)

for results in query:
    for result in results:
        print(result.replace("\n", ""))

출력:

When working with regular expressions, the sub() function of the re library is an invaluable tool.
the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found

정규식 설명을 더 잘 이해하기 위해 각 그룹별로 분석하고 각 부분이 수행하는 작업을 살펴보겠습니다.

첫 번째 캡처링 그룹 ([^\n\r]+)에서 줄 바꿈 기호 또는 캐리지 리턴 문자를 제외한 모든 문자가 가능한 한 자주 일치합니다.

그런 다음 [\n\r] 식에서 문자가 캐리지 리턴이거나 개행인 경우 일치가 이루어집니다.

두 번째 캡처 그룹 ([a-z \n\r]+)에서 a-z 사이의 문자 또는 개행 또는 캐리지 리턴이 가능한 한 많이 일치합니다.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

관련 문장 - Python Regex