정규 표현식: 정확히 반복되는 토큰 수만큼 전체 줄과 일치시키는 방법

2024-04-02

정규 표현식(regex)을 사용하여 정확히 반복되는 토큰 수만큼 전체 줄과 일치시키는 방법

기본 개념

1 토큰

토큰은 정규 표현식에서 문자열의 기본 단위입니다. 토큰은 문자, 숫자, 특수 문자 또는 문자 그룹일 수 있습니다. 예를 들어, 다음 정규 표현식에서 토큰은 다음과 같습니다.

a.b
  • a: 문자 a
  • .: 임의의 문자
  • b: 문자 b

2 반복

정규 표현식에서 토큰을 반복하려면 +, * 또는 ? 연산자를 사용합니다.

  • +: 토큰이 1번 이상 반복되어야 합니다.
  • *: 토큰이 0번 이상 반복될 수 있습니다.
  • ?: 토큰이 0번 또는 1번 반복될 수 있습니다.

예를 들어, 다음 정규 표현식은 a가 1번 이상 반복된 모든 문자열과 일치합니다.

a+

Lookaround는 정규 표현식이 일치하는 위치를 제한하는 데 사용됩니다. 긍정적 lookaround ((?=...))는 특정 패턴이 현재 위치 바로 뒤에 있어야 일치하는 것을 확인합니다. 부정적 lookaround ((?!...))는 특정 패턴이 현재 위치 바로 뒤에 없어야 일치하는 것을 확인합니다.

a(?=b)

정확히 반복되는 토큰 수만큼 전체 줄과 일치시키기

다음은 정확히 n번 반복되는 토큰 x만큼 전체 줄과 일치시키는 정규 표현식입니다.

^x{n}$
  • ^: 문자열의 시작과 일치
  • x{n}: 토큰 xn번 반복
  • $: 문자열의 끝과 일치
^a{3}$

1 예시

다음은 정규 표현식 ^x{n}$을 사용하는 몇 가지 예시입니다.

  • 입력: aaa

  • 정규 표현식: ^a{3}$

  • 결과: 일치

lookaround를 사용하여 줄의 시작과 끝을 확인하기

^$ 연산자는 문자열의 시작과 끝을 확인하는 데 유용하지만, 특정 토큰이 줄의 시작 또는 끝에 있는지 확인하는 데는 사용할 수 없습니다. 이 경우 lookaround를 사용해야 합니다.

(?m)^x{n}$
  • (?m): 멀티라인 모드 활성화. 각 줄을 개별적으로 처리합니다.
  • 입력:
aaa
bbb
aaaaa
  • 정규 표현식: (?m)^a{3}$
  • 결과: 첫 번째 줄과 세 번째 줄만 일



예제 코드

import re

def match_line(line, pattern):
  """
  정규 표현식 패턴과 일치하는지 확인합니다.

  Args:
    line: 문자열
    pattern: 정규 표현식 패턴

  Returns:
    True if the line matches the pattern, False otherwise.
  """
  return re.match(pattern, line)

# 테스트 코드
lines = [
  "aaa",
  "abca",
  "aaaaa",
  "aaa\nbbb\naaaaa",
]

pattern = "^a{3}$"

for line in lines:
  print(f"Line: {line}")
  print(f"Match: {match_line(line, pattern)}")
  print()

출력:

Line: aaa
Match: True

Line: abca
Match: False

Line: aaaaa
Match: False

Line: aaa
bbb
aaaaa
Match: True
Match: False
Match: True



정확히 반복되는 토큰 수만큼 전체 줄과 일치시키는 대체 방법

문자열 슬라이싱

다음은 Python에서 문자열 슬라이싱을 사용하여 정확히 3번 반복되는 문자 a만큼 전체 줄과 일치시키는 코드입니다.

def match_line(line):
  """
  정확히 3번 반복되는 문자 'a'만큼 전체 줄과 일치하는지 확인합니다.

  Args:
    line: 문자열

  Returns:
    True if the line matches the pattern, False otherwise.
  """
  return line == "aaa"

# 테스트 코드
lines = [
  "aaa",
  "abca",
  "aaaaa",
]

for line in lines:
  print(f"Line: {line}")
  print(f"Match: {match_line(line)}")
  print()

출력:

Line: aaa
Match: True

Line: abca
Match: False

Line: aaaaa
Match: False

for 루프

def match_line(line, x, n):
  """
  정확히 n번 반복되는 토큰 'x'만큼 전체 줄과 일치하는지 확인합니다.

  Args:
    line: 문자열
    x: 토큰
    n: 반복 횟수

  Returns:
    True if the line matches the pattern, False otherwise.
  """
  if len(line) != n * len(x):
    return False

  for i in range(n):
    if line[i * len(x)] != x:
      return False

  return True

# 테스트 코드
lines = [
  "aaa",
  "abca",
  "aaaaa",
]

x = "a"
n = 3

for line in lines:
  print(f"Line: {line}")
  print(f"Match: {match_line(line, x, n)}")
  print()
Line: aaa
Match: True

Line: abca
Match: False

Line: aaaaa
Match: False

장단점 비교

방법장점단점
정규 표현식간결하고 읽기 쉽습니다.복잡한 패턴을 처리하기 어려울 수 있습니다.
문자열 슬라이싱간단하고 직관적입니다.문자열의 길이가 변동될 경우 코드를 수정해야 합니다.
for 루프모든 경우에 적용할 수 있습니다.코드가 다소 복잡해질 수 있습니다.

결론


regex regex-lookarounds


대체 방법: 정규 표현식 없이 전화번호 유효성 검사

전화번호 형식은 국가마다 다릅니다. 하지만, 일반적으로 다음과 같은 요소들을 포함합니다.국가 코드: 국가를 식별하는 숫자입니다. 예를 들어, 미국은 +1, 한국은 +82입니다.지역 코드: 특정 지역을 식별하는 숫자입니다...


정규 표현식과 부정 표현식을 이용한 특정 단어 미포함 행 일치

정규 표현식은 문자열 패턴을 검색하는 데 유용한 도구이지만, 특정 단어가 포함되지 않은 행을 일치시키는 데 어려움을 겪을 수 있습니다. 부정 표현식을 사용하여 이 문제를 해결할 수 있지만, 다소 복잡하고 직관적이지 않을 수 있습니다...


regex lookarounds