[Module] re module, 정규표현식

고보·2024년 2월 1일

1 re module

  • 정규표현식(regular expression)을 사용해 문자열을 처리하는 데 사용하는 파이썬 표준 라이브러리.
  • https://regex101.com/ 참고 사이트

1-1 자주 쓰는 메서드

  • search(pattern, string): 첫 번째로 찾은 패턴 찾기. Match 객체 반환.
    • re.search('world', 'hello world').group() => world
    • .group()을 적용하면 매치된 문자열 반환, .start() .end()하면 시작 위치 끝 위치 반환.
    • flags=re.IGNORECASE를 매개변수로 넣으면, 대소문자 구분 안한다.
  • match(pattern, string): 문자열의 시작에서 패턴이 일치하는지를 확인. 일치하면 Match 객체로 반환. 일치 안하면 None 반환.
    • re.match('world', 'hello world').group() => 안 맞으면 None 반환. world로 시작하지 않기 때문에.
    • .group()하면 일치하는 내용 꺼낼 수 있고, bool(match객체)하면 True로도 꺼낼 수 있다.
  • fullmatch(pattern, string): 주어진 정규표현식 패턴이 문자열과 정확히 일치하는지. 마찬가지로 일치하면 Match 객체로 반환, 일치 안하면 None 반환.
  • split(pattern, string): 정규 표현식을 기준으로 문자열을 분할해서 리스트로 반환.
    • maxsplit = 으로 최대 분할 횟수 지정.
# 공백 문자를 기준으로 문자열 분할
result = re.split(r'\s+', 'One two     three\nfour\tfive')
print(result)
# 출력: ['One', 'two', 'three', 'four', 'five']

# 콤마, 세미콜론, 공백 등을 포함한 복잡한 분할 조건
text = 'apple,banana; orange, lemon, lime'
result = re.split(r'[;,\s]\s*', text)
print(result)
# 출력: ['apple', 'banana', 'orange', 'lemon', 'lime']

# 최대 분할 횟수 지정
result = re.split(r'\s+', 'One two three four five', maxsplit=2)
print(result)
# 출력: ['One', 'two', 'three four five']
  • findall(pattern=, string=, flags=0): 문자열에서 시작 패턴과 일치하는 모든 부분을 찾아 리스트로 반환.
    • re.findall(r'\d+', 'the 10 and 20') => [10, 20] 반환
  • finditer(pattern, string, flags=0): 문자열에서 패턴과 일치하는 모든 부분을 찾아 callable_iterator로 반환. 그 내부를 하나씩 꺼내면, 하나하나가 Match 객체다.
    • 아래를 보면 matches에서 for문으로 하나하나 꺼내면, match 객체. 그걸 .group()으로 텍스트를 꺼내면, 각각 rain, spain이 나온다.
text = "The rain in Spain"
pattern = r"\b\w+ain\b"
matches = re.finditer(pattern, text)
for match in matches:
    print(match.group()) 
  • sub(pattern, repl, string, count=0): 문자열에서 패턴과 일치하는 부분을 다른 문자열로 대체. 패턴, 대체할 문자열, 대상 문자열.
    • count=매개변수로 최대 횟수.
    • re.sub(r'\d+', '100', 'the 10 and 20') => 'the 100 and 100'
  • compile(): 데이터 처리하다보면 패턴 반복해서 사용해야할 때, compile()함수로 패턴 재사용 가능. 정규식을 변수에 직접 저장하는 대신 compile()함수로 패턴을 컴팡리하고, 변수에 저장해서 사용. 그런 다음 컴파일된 패턴에 다른 re 모듈 함수 적용.
p = re.compile('\d{10}')
s = '1234567890'
m = p.match(s) #p는 앞서 컴파일해놓은 정규표현식

1-2 Match 객체에 쓰는 메서드들

  • m.group(): Match 객체에서 그룹화(()로 묶인)것을 반환. ()면 찾아낸 패턴 전체를 반환, 특정 그룹 반환. (1)은 첫 번째 그룹 반환.
  • m.groups(default=None): Match 객체에서 찾아낸 패턴 모든 그룹을 튜플로 반환. group이 해당 것만 반환했다면.
  • m.groupdict(default=None): Match 객체에서 찾아낸 패턴 모든 이름이 지정된 그룹을 딕셔너리로 반환합니다.
  • m.start(): 찾은 패턴의 첫 번째 인덱스 반환
  • m.end(): 찾은 패턴의 마지막 인덱스 반환
  • m.span(): 찾은 패턴의 첫 번째와 마지막 인덱스 반환

2 정규표현식(regular expression)

  • 문자열 패턴을 찾아 대체하기 위한 규칙
  • \d: 숫자
    re.findall(r'\d', 'Hello 123 World 456') => ['1', '2', '3', '4', '5', '6']
  • \d+ 하나 이상의 숫자
    re.findall(r'\d+', 'Hello 123 World 456') => ['123', '456']
  • \d{2}: 숫자 2개
    re.findall(r'\d{2}', 'Hello 123 World 45678') => ['12', '45', '67']
  • \D: 숫자 외 글자
    re.findall(r'\D', 'Hello 123 World 456') => ['H', 'e', 'l', ~~~]
  • \w: 단어 문자(word character). 알파벳, 숫자, _ 밑줄.(space 미포함)
    re.findall(r'\w', 'Hello 123 World 456') => ['H', 'e', 'l', ~~~, '1', '2', '3', ~~]
  • .: 줄 바꿈을 제외한 어떤 글자든. space포함. \n은 미포함. => .하면 문자 .
  • yo*b: 저 형태 앞에서 *의 바로 앞의 문자가 몇 번씩 반복되고 있는 부분.
pattern = r'yo*b'
text = 'yob, yoob, yobb, yooobb, yooobc'
matches = re.findall(pattern, text)
  • ['yob', 'yoob', 'yob', 'yooob', 'yooob'] 이렇게 리턴된다.
  • ^: ^뒤에 오는 글자를, 시작하는 부분에서만 찾아서 반환
    re.findall(r'^a', 'apple apple') => ['a'] 반환. 띄어쓰기 있어도 시작 아니고, 개행 문자(줄 바꿈, \n) 뒤의 것만 포함.
    re.findall(r'^p', 'apple apple') => [''] 반환.
    re.findall(r'^ap', 'apple apple') => ['ap'] 반환.
  • $: $ 앞에 오는 글자로 끝나는 부분을 찾음.
    re.findall(r'ld$', 'hello world') => ['ld'] 반환.
    re.findall(r'lo$', 'hello world') => [''] 반환.
  • []: 대괄호 안에 있는 문자 중 하나와 일치하는 패턴
    re.findall(r'[aeiou]', 'hello world') => ['e', 'o', 'o']
  • \b: 단어 경계. 단어 경계는 단어와 비단어(공백, 구두점) 사이의 위치.
    year = re.findall(r'\b20\d{2}\b', i) => ~. 2001; ~ 이런 류의 이름 파일.
    re.findall(r'\bcat\b', 'cat scatter cath concate') => ['cat'] 두 번째 이후로는 경계로 안나눠져있어서
  • (): 그룹 묶기 => \(\)글자로서 ()
    re.findall(r'(\d{3})-(\d{4})', 'dafds 123-4567' => [('123', '4567')]
  • \1, \2: 그룹1, 그룹2을 표현한다. 아래와 같이 하면 World Hello가 출력된다.
pattern = r'(\w+)\s+(\w+)'

# 문자열에서 패턴에 매칭되는 부분을 찾아내기
text = 'Hello World'
match = re.search(pattern, text)

# 그룹을 사용하여 단어 순서를 바꾸기
reversed_text = re.sub(pattern, r'\2 \1', text)

# 결과 출력
print(reversed_text)
  • \s: 공백
  • ?: 앞의 글자가 있어도 되고 없어도 된다.
    \d{3}\s?\d{3}\s?\d{4}면 \s가 있어도 되고 없어도 된다. 즉, 123 456 7890과 123456 7890 모두 패턴 일치.
  • r'': r-string으로 정규표현식과 일반문자열 구분
  • 복잡해지면 스스로 다시 봐도 어려우니까, 하나씩 개행해서 #로 줄별로 표현

3 regex 라이브러리

  • 더 많고 복잡한 정규표현식을 지원. 특히 다양한 언어와 문자 체계 다룰 수 있어서, 국제화된 애플리케이션 개발에 사용.
  • 외부 라이브러리라서 설치 필요.
profile
일본에서 일하는 게임 기획자. 시시해서 죽어버리지 않게, 재밌고 의미 있는 컨텐츠에 관심 있습니다. 그 도구로 데이터, AI도 찝적댑니다.

0개의 댓글