1 re module
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)
text = 'apple,banana; orange, lemon, lime'
result = re.split(r'[;,\s]\s*', text)
print(result)
result = re.split(r'\s+', 'One two three four five', maxsplit=2)
print(result)
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)
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 라이브러리
- 더 많고 복잡한 정규표현식을 지원. 특히 다양한 언어와 문자 체계 다룰 수 있어서, 국제화된 애플리케이션 개발에 사용.
- 외부 라이브러리라서 설치 필요.