정규표현식(Reg)

출처 : https://github.com/aloverso/SoftwareSystems/wiki/Deep-Dive-Haley-Grep,-Sed,-Awk

정규표현식

프로그래머스 정규표현식 강의를 들으면서 작성한 노트이다. 강의는 파이썬으로 진행되었다.

ToC


숫자 대표문자 (한 글자만)

  • \d : 숫자를 대표하는 정규표현식 (d:digit)

강의에서 계속 아래의 예제코드를 사용하게 된다.

1
2
3
4
5
6
7
8
9
regex = r'\d'

search_target = '''Luke Skywarker 02-123-4567 luke@daum.net
다스베이더 070-9999-9999 darth_vader@gmail.com
princess leia 010 2454 3457 leia@gmail.com'''

import re
result = re.findall(regex, search_target)
print("\n".join(result))

출력결과

result 라는 변수가 print 함수에 의해 출력되었는데, result 함수를 뜯어보면, search_target 에서 regex 가 일치하는 부분만 뽑아서 한글자씩 저장이 된거다.

여기서 내가 작성한건 regex 변수 정의하는 부분에서 \d 를 채워넣었다. 여기서 \d 는 숫자(digit)를 대표하는 정규표현식이라고 한다.


글자 대표문자 (한 글자만)

  • \w : 글자를 대표하는 정규표현식 (w:word)

  • a, b, c와 같은 알파벳 문자와 가,나,다 와 같은 한글문자, 1,2,3 같은 숫자까지 포함.

  • 특수문자는 포함안되더라도 _ 는 포함된다고 한다.

출력결과

숫자 대표문자 \d 와 마찬가지로 변수 regex\w 를 작성하고 실행했다.

search_target 에서 regex 에 일치하는 결과물을 출력하는 코드이다. 스크린샷에서는 다 출력하지 못했지만, 숫자와 한글까지 다 정확히 출력된걸 확인할 수 있었다.


문자 여러개

  • \d는 숫자 한 글자씩만 찾는 한계가 있다. 한 글자로 이루어진 단어뿐 아니라 여러 글자로 이루어진 단어로 찾을땐 \d+ 를 이용한다.

출력결과

숫자로 이루어진 글자를 한글자씩 떼네어 잘 출력이되었다. \w+ 로 조회해보면, 마찬가지로 문자를 한 글자가 아닌 한 단어씩 조회가 된다.


0개 이상

  • * 은 특정 조건으로 최소한 1개 이상의 수를 조회한다.
  • [1-9]\d* : 앞자리 숫자가 1과 9중 하나가 반드시 나오는 수를 조회한다. 즉 자연수를 찾는 방법이다.
  • \d*[9] : 뒤에다 붙이면, 뒷자리 숫자가 9인 숫자를 조회한다.

출력결과


x가 있을수도 있고, 없을 수도 있고

  • x? : x가 있을수도 있고, 없을수도 있는 조건을 포함시켜 조회할 때 사용한다.
  • [x]? 로 작성할 수도 있다.

강의에서 사용한 예제는 전화번호이다. 찾고자 하는 전화번호가 같은번호임에도 - 여부에 따라 021234567 일수도있고, 02-123-4567 일수도 있다.
이때 -? 를 포함시켜 조회하면, - 가 있거나 없거나 모두 조회하게 된다.

전화번호 형태의 숫자를 조회해보았다.

전화번호(xxx-xxx-xxx)는 숫자(\d+) 3개 사이에 각각 - 가 포함될수도있고, 그렇지 않을수도 있기 때문에 정규표현식으로 작성해보면 \d+ , -?, \d+, -?, \d+ 를 이어붙인걸로 작성될 수 있다. \d+-?\d+-?\d+

출력 결과


x 또는 y가 있을수도 있고, 없을 수도 있고

  • [x,y]? : x 또는 y가 있을수도 있고, 없을 수도 있다.

전화번호 예제를 계속 사용해보면, 사실 - 뿐 아니라 그냥 공백으로 전화번호를 구분하는 표기법도 있다. 그럼 의 정규표현식 \d+-?\d+-?\d+ 로는 공백으로 구분한 전화번호는 조회되지 않는다.

이땐 ? 앞에 - 대신 [- ] 를 작성하면, -또는 이 있을수도 있고, 없을 수도 있는 조건이 추가되어 조회된다.

출력 결과


특정 글자 수의 문자만 조회

  • \d{n} : n개로 이루어진 숫자 단어를 조회할 때 사용

전화번호 형태가 최근 가장 많이 쓰이는 휴대전화번호인 xxx-xxxx-xxxx 라면 위에서 사용한 정규표현식(\d+[- ]?\d+[- ]?\d+)만으로는 부족할 것이다. \d+ 는 글자수와 상관없이 한 단어로 구성된 모든 숫자를 조회하기 때문이다.

이때 \d{} 를 사용하면, 원하는 글자 갯수로 구성된 단어만을 조회할 수 있다.

일반적으로 많이 사용하는 휴대전화번호 포맷인 xxx-xxxx-xxxx를 조회하기 위해서는 정규표현식을 \d{3}[- ]?\d{4}[- ]?\d{4} 로 수정해야 한다.

출력 결과


글자 수 조건 추가하여 문자 조회

  • \d{x, y} : x또는 y개로 구성된 숫자 단어 조회

전화번호 포맷이 xxx-xxxx-xxxx 일 수도 있지만, xx-xxx-xxxx 이거나 xxx-xxx-xxxx 라면 \d{n} 만으로는 전체 전화번호 조회가 불가능하다. 따라서 찾고자 하는 단어의 갯수의 조건을 추가해야 한다.

앞자리 숫자가 3자리 일수도 있고, 2자리일수도 있으니 \d{2,3}
중간 숫자는 3자리 일수도 있고, 4자리 일수도 있으니 \d{3,4}
마지막 숫자는 4자리 수이므로 그냥 \d{4}

중간에 - 또는 공백이 있을수도 있고, 없을수도 있는 정규표현식([- ]?)까지 채워넣으면 최종적으로 아래의 정규표현식이 완성된다.

\d{2,3}[- ]?\d{3,4}[- ]?\d{4}

출력 결과


특정 문자만 조회

  • [xyz] : x, y, z만 조회한다.

소음자 모음(a,e,i,o,u)문자만 조회를 해보았다.

출력 결과


소문자 알파벳 전체를 조회하기

  • [a-z] : a부터 z에 해당하는 소문자 알파벳 전체를 조회한다.
  • [a-z]+ : 소문자로만 이루어진 단어 조회

출력결과


한글단어 조회

  • [가-힣] : 한글의 첫 글자는 이고, 마지막 글자는 라고 한다.

한글로 구성된 단어를 찾을 땐 [가-힣]+ 로 조회할 수 있다.

출력 결과


기타 대표문자

  • \s : 공백문자 (스페이스, 탭, 뉴라인)
  • \S : 공백문자를 제외한 문자
  • \d : 숫자 대표문자
  • \D : 숫자를 제외한 문자
  • \w : 글자 대표 문자
  • \W : 글자 대표 문자를 제외한 문자 (특수문자, 공백)

출력 결과

숫자를 제외하고 조회

글자 대표문자 제외하고 조회

자바 정규표현식

자바에서는 정규표현식을 작성할때 앞에 \ 을 더 붙여줘야 한다. 자바에선 기본적으로 \ 이 escape를 의미하기 때문이다.

따라서 3글자 숫자로만 구성된 단어를 조회한다면, 작성할 수 있는 정규표현식은 다음과 같을 것이다. \\d{3}

Python에서는 re 를 import하고, re.findall() 로 조회를 했다.

자바에서는 Pattern 클래스와 Matchers 클래스를 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.regex.Pattern;
import java.util.regex.Matchers;

public class study_regex {
public static void main(String[] args){
String target = "Luke Skywarker 02-123-4567 luke@daum.net\n다스베이더 070-9999-9999 darth_vader@gmail.com\nprincess leia 010 2454 3457 leia@gmail.com";

// 숫자를 포함한 단어(\w) 조회
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(target);

while(matcher.find()){
System.out.println(matcher.group(0));
}
}
}

출력 결과