파이썬과 자바스크립트의 정규표현식 사용법

hyun·2022년 9월 15일
2

프론트엔드

목록 보기
5/8
post-thumbnail

이 포스트에서 다룰 것

지난 포스트에서는 정규표현식의 기본 문법에 대해 학습했다. 아는 만큼 보인다더니, 정규식을 공부하고 나니 실무와 알고리즘 문제에서도 정말 유용하게 쓰이는 걸 느꼈다. 내가 정리한 블로그 글을 내가 제일 많이 들어가서 다시 본 것 같다(기술블로그의 장점을 잘 활용하는 것 같아 뿌듯하다). 이제 열심히 공부한 정규식 문법을 실전에서 써먹는 방법을 알아보려고 한다. 자바스크립트와 파이썬에서의 정규표현식 사용 방법을 예제코드와 함께 정리한다.

TMI

프로그래머스의 파일명 정렬이라는 문제를 풀다가 이 포스트를 작성하게 되었다. 2단계이지만 정규표현식을 이용하면 간단하게 풀린다. 이 문제도 풀이방법을 포스팅할 것이다.

파이썬

re 라이브러리

파이썬에서 정규표현식을 사용하려면 re라는 라이브러리를 사용해야 한다. 문자열 내 특정 패턴을 검색하거나 치환, 삭제할 수 있는 기능을 제공하는 Regular Expression 라이브러리이다.

re가 패턴을 인식하는 방법

  1. 사용자가 정규표현식을 정의한다.
  2. re에 1에서 정의한 정규표현식을 집어넣으면 정규식 객체가 생성된다.
  3. 생성된 정규식 객체는 자동으로 문자열 내의 패턴을 감지해 원하는 기능을 수행한다.
import re

당연하게도 라이브러리이기 때문에 위처럼 import를 해 줘야 사용이 가능하다. 그러면 이제 re에서 제공하는 주요 메소드들을 살펴보자.

📌 re.search(pattern, string)

문자열을 스캔하여 정규식에 맞는 첫 번째 위치를 찾아 리턴한다. 찾지 못하면 None을 리턴한다.

import re
pattern = "([0-9]+년)\s*([0-9]+월)\s*([0-9]+일)"
ret = re.search(pattern, "오늘은 2022년 9월 16일이고요, 내일은 2022년 9월 17일입니다.")

print(ret)  # <re.Match object; span=(4, 16), match='2022년 9월 16일'>

날짜를 찾아내는 간단한 정규식 예제이다. 첫 번째로 인식된 숫자 3이 ret 정규식 객체에 담겨 반환되었다.

# 패턴 시작 start index
ret.start() # 4

# 패턴 끝 end index
ret.end() # 16

# 인식한 문자열 출력
ret.group() # '2022년 9월 16일'
ret.group(0) # '2022년 9월 16일'

ret.group(1) # '2022년'
ret.group(2) # '9월'
ret.group(3) # '16일'

# 부분적으로 인식된 문자열 출력
ret.groups() # ('2022년', '9월', '16일')

정규식에서 그룹을 지정해주는 괄호()에 해당하는 패턴을 그룹으로 가져올 수도 있다.

📌 re.match(pattern, string)

re.search()와 유사하게 검색을 하는 함수지만, 차이가 있다.
search는 문자열의 아무 곳에서나 일치하면 인식하는 반면, match문자열의 시작 부분에서만 일치를 검사한다. 일치하는 패턴이 없는 경우 None을 리턴한다.

import re
string = 'a@a.com, b@b.net'
pattern = "[a-z]+@[a-z]+\.net"
match_result = re.match(pattern, string)
search_result = re.search(pattern, string)

print(match_result) # None
print(search_result) # <re.Match object; span=(9, 16), match='b@b.net'>

.net 이메일 패턴을 찾는 정규식을 match의 파라메터로 넣어보았다. 일치하는 패턴은 string의 뒷 부분에 있으므로 match의 결과는 None이다. 한편 search는 위치 상관없이 인식하므로 .net을 잘 찾아낸다.

📌 re.split(pattern, string)

문자열을 패턴을 기준으로 쪼개어 리스트를 반환해준다.

import re
pattern = "[0-9]"
ret = re.split(pattern, "abc1def")

print(ret) # ['abc', 'def']

📌 re.sub(pattern, repl, string)

string에서 pattern을 찾아 repl으로 치환해준다.

import re
pattern = "[0-9]"
ret = re.sub(pattern, "x", "비밀번호는 1234입니다")

print(ret) # '비밀번호는 xxx입니다'

정규식 패턴에 맞는 숫자가 x로 치환된 것을 확인할 수 있다.

📌 re.compile(pattern)

정규식 패턴을 정규색 객체로 컴파일한다.

import re
obj = re.compile("[0-9]+")
ret = obj.search("숫자검색 1234")

print(ret) # <re.Match object; span=(5, 9), match='1234'>

ret.start() # 5
ret.end() # 9 

컴파일한 객체에 위에서 공부한 메소드들을 적용할 수 있다. 하나의 정규식 패턴을 여러 번 사용할 때 compile을 사용하면 정규식 객체를 여러 개 생성하지 않아도 되니 효율적이다.

자바스크립트

자바스크립트에도 파이썬과 유사한 기능을 하는 메서드들이 있다. 정규식 표현방법과 주요 메소드를 살펴보자.

정규식 선언 방법

// 리터럴 방식
const regex = /abc/;
 
// 생성자 방식
const regex = new RegExp("abc");

슬래시 사이에 정규식을 넣거나, new RegExp() 구문을 이용해서 생성하거나의 두 가지 방법으로 정규식을 선언할 수 있다.

플래그

자바스크립트에서는 정규식 뒤에 플래그를 붙여 탐색 옵션을 지정할 수 있다.

플래그 의미 설명
i ignore 대소문자를 구별하지 않고 검색한다.
g global 문자열 내의 모든 패턴을 검색한다.
m multiline 문자열의 행이 바뀌더라도 계속 검색한다.
s .(모든 문자 정규식)이 개행문자 \n도 포함하도록
u unicode 유니코드 지원

🏁 g (전역 검색)

전역 검색 플래그가 없는 경우에는 최초 검색 결과만 반환하는 반면, 전역 검색 플래그가 있는 경우에는 모든 검색 결과를 배열로 반환한다. 마치 파이썬의 re.match()와 유사하다.

const str = "abcabc";
 
// `g` 플래그 없이는 최초에 발견된 문자만 반환
str.match(/a/);
// ["a", index: 0, input: "abcabc", groups: undefined]
 
// `g` 플래그와 함께라면 모든 결과가 배열로 반환
str.match(/a/g);
// (2) ["a", "a"]

🏁 m (줄바꿈 검색)

여러 줄의 정규식 문자열이 실제 여러 줄로써 다루어져야 할 때 사용되며, 아래에서 알아볼 입력 시작(^)과 입력 종료($)가 전체 문자열이 아닌 각 줄 별로 대응된다.

// 줄바꿈이 포함된 문자열
var str = "\nIs th\nis it?";
 
str.match(/^is/m); // is
 
 
// `` 는 "",''과 달리 개행문자를 포함하여 문자열 구성 가능.
const str = `abc
add`;
 
// 한줄만 검사
str.match(/c$/g); // ["c"]
 
// 줄마다 검사
str.match(/c$/g); // (2) ["c", "c"]

🏁 i (대소문자 무시)

정규식은 기본적으로 대소문자를 구분하지만 i 플래그를 옵션으로 달면 대소문자르 무시한다.

const str = "abcABC"
str.match(/a/gi);
// (2) ["a", "A"]

정규식 주요 메소드

문자열에 적용할 수 있는 주요 메소드를 정리한다.

📌 str.search(pattern)

정규표현식을 인자로 받아 가장 처음 매칭되는 부분 문자열의 위치를 반환한다. 매칭되는 문자열이 없으면 -1을 반환한다. 파이썬이랑 똑같다.

"JavaScript".search(/script/); // -1 대소문자를 구분합니다
"JavaScript".search(/Script/); // 4

📌 str.match(pattern)

문자열에서 패턴과 일치하는 결과를 배열로 리턴한다. 일치하는 결과가 없을 시 null을 리턴한다.

let pattern = /p/;
let str = 'apple';
str.match(pattern);

📌 str.replace(pattern, repl)

정규식과 치환하려는 문자를 인자로 받고, 문자열에서 패턴을 검색 후 치환한다. 파이썬의 re.sub(pattern, repl, str)과 같다.

let pattern = /\d/; 
let str = '비밀번호는 1234입니다'; 
let ret = str.replace(pattern, 'x'); // '비밀번호는 x234입니다'

숫자를 x로 바꾸는 코드를 작성했는데, 첫 번째만 바뀌었다. 모두 바꾸고 싶으면 어떻게 해야 할까?

let pattern = /\d/g;
let str = '비밀번호는 1234입니다'; 
let ret = str.replace(pattern, 'x'); // '비밀번호는 xxxx입니다'

위에서 배운 전역 플래그를 사용하면 된다.

📌 str.split(separator)

주어진 인자를 구분자로 삼아, 문자열을 부분 문자열로 나누어 그 결과를 배열로 반환한다.

"123,456,789".split(",")  // ["123", "456", "789"]
"12304560789".split("0")  // ["123", "456", "789"]

레퍼런스

파이썬 참고 블로그
자바스크립트 참고 블로그
자바스크립트 참고 블로그 2

profile
프론트엔드를 공부하고 있습니다.

0개의 댓글