39
정규표현식 김주희 1

정규표현식(Regular expressions)

Embed Size (px)

DESCRIPTION

정규표현식(Regular expressions) ppt

Citation preview

Page 1: 정규표현식(Regular expressions)

정규표현식

김주희

1

Page 2: 정규표현식(Regular expressions)

목차

I. 정규표현식소개 (3~4)

II. POSIX 스타일의 정규표현식 (5~12)

III. Perl 호환 정규표현식 (13~24)

IV. 프로그래밍을 위한 정규표현식 (25~29)

V. Regular Expression Reference (30~33)

Page 3: 정규표현식(Regular expressions)

정규표현식 소개

3

Page 4: 정규표현식(Regular expressions)

정규표현식 소개 – 정규표현식이란?

• regular expression

– 간단히, regexp 또는 regex

• 주로 Programming Language, Text Editor 등에서 문자열의 검색과 치환을

위한 용도로 사용

• 입력한 문자열에서 특정한 조건을 표현할 경우, 정규표현식을 이용하면 매

우 간단하게 표현

– But, 코드가 간단한 만큼 가독성이 떨어져서 표현식을 숙지하지 않으면 이해하기

어려움

4

Page 5: 정규표현식(Regular expressions)

정규표현식 소개 – 정규표현식 스타일

• 대표적인 정규표현식 스타일

– POSIX(Portable Operating System Interface)

• 유닉스 운영체계에 기반을 두고 있는 일련의 표준 운영체계 인터페이스

• 간단해서 배우기 쉽고 실행속도가 빠르며 사용하기 용이

– PCRE(Perl Compatible Regular Expression, 펄 호환 정규 표현식)

• POSIX 정규표현식에서 확장된 Perl방식

Perl: 임의의 형태를 갖춘 텍스트 파일을 읽고, 이 파일에서 의미 있는 정보를 추출하여,

이 정보를 근거한 레포트를 출력하는 작업에 최적화된 언어이며, 시스템 관리에도 매우 적절한 언어

• 대부분의 언어에서 라이브러리를 제공하므로 확장성이 뛰어남

• Perl, .NET, Java, JavaScript, Python

• 정규표현식간에는 약간의 차이점이 있으나 거의 비슷

5

Page 6: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식

6

Page 7: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – egrep 이용 – 문자열 찾기

• 예제) rime-index.txt

1) 대문자로만 이루어진 문자 찾기

– 결과

2) 탭이 포함된 문자열 찾기

– 결과

[A-Z] 영어 대문자 [a-z] 영어 소문자 [1-9] 숫자 ? 1개 이하 * 0개 이상 + 1개 이상

cat rime-intro.txt | egrep [A-Z] | egrep -v [a-z]

egrep ‘ctrl+v tab’ rime-intro.txt

7

Page 8: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – egrep 이용 – 문자열 찾기

• 예제) telephonelist.txt

1) 유효한 전화번호 찾기

• 결과

x{n} x를 n번 반복 x{n,} x를 n번 이상 반복 x{n,m} x를 n번이상 m번이하 반복

egrep -n '\([0-9]{3}\) [0-9]{3}[.-]?[0-9]{4}' telephonelist.txt

8

Page 9: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – sed 이용 – 문자열 추가하기

• 예제) rime.txt

1) sed를 사용하여 마크업 추가하기

– 결과

^ 행의 시작을 찾는다 $ 행의 끝을 찾는다 <sed 명령어> s 대체(substitute) 예. s/찾을문자열/바꿀문자열/ -n 정규표현식이 적용된 행만 출력 -e 명령어 이어 붙이기 p 모든행을 무조건 출력 q 프로그램 종료

sed -ne 's/^/<h1>/' -e 's/$/<\/h1>/p' -e 'q' rime.txt

9

Page 10: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – sed 이용 – 그룹 사용하기

• 예제) rime.txt

1) 두 가지 이상의 패턴 중 하나를 선택

2) 정확한 단어 찾기

– 결과

\< 단어의 시작을 찾는다 \> 단어의 끝을 찾는다 ( ) ( )안의 내용을 그룹화, reference 생성

egrep -n ‘(the|The|THE)’ rime.txt

egrep -n ‘\<(the|The|THE)\>’ rime.txt

10

Page 11: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – sed 이용 – 그룹 사용하기

• 예제) rime.txt

1) sed로 첫번째 행에 나오는 문장에 앞 뒤에 <title> </title> 로 대체하기

– 결과

2) sed로 빈줄은 <br/>로 대체하기

– 결과

. 임의의 모든 문자(개행문자 제외) ( ) ( )안의 내용을 그룹화, reference 생성 \숫자 back reference (예 \1, \2 ...) <sed 명령어> 숫자s 숫자(n)행의 내용 표시(예 1s, 2s ...) -E back reference 사용 가능

sed –E '1s/^(.*)$/ <title>\1<\/title>/;q' rime.txt

sed –E ‘s/^$/<br\/>/' rime.txt

11

Page 12: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – vim에서 정규표현식 사용 – 문자열 바꾸기

• 예제) telephonelist.txt

1) 지역번호 바꾸기

• 결과

<vim 명령어> / 검색 :s/찾을문자열/바꿀문자열/옵션 치환 <옵션> c 대화형 치환 g 모두 치환 옵션없음 처음 match되는 부분만 치환

:%s/032/02/c

12

Page 13: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – vim에서 정규표현식 사용 – 범위 지정하기

13

• 예제) tag.txt

1) <B>문자열</B> 찾기

.* (Greedy Quantifier) vs .? (Lazy Quantifier)

Vim 에서는 Lazy Quantifier 가 *? 로 지원되지 않으므로 -를 이용해 {-0,} 과 같이 사용

2) 배경색을 나타내는 코드 찾기

<[Bb]>.*<\/[Bb]>

{-0,} 1개 이하 *? 와 같은 기능 lazy quantifier 제일 짧은 비교영역부터 검색 [[:xdigit:]] 16진수

\#[[:xdigit:]]\{6\}

<[Bb]>.\{-0,\}<\/[Bb]>

Page 14: 정규표현식(Regular expressions)

POSIX 스타일의 정규표현식 – less 사용 – URL 찾기

• 예제) url.txt

1) URL 찾기

• 결과

\<((https?|ftp|file)://|(docs|www|ftp)\.)[-a-zA-Z0-9+&@#/%?=~_|$!:,.;]*[a-zA-Z0-9+&@#/%=~_|$]\>

14

Page 15: 정규표현식(Regular expressions)

Perl 호환 정규표현식

15

Page 16: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 리터럴 텍스트에 일치

• Problem

– 다음 문장에 정확히 일치되는 정규식을 작성

– The punctuation characters in the ASCII table are: !”#$%&’( )*+,-/:;<=>?@[\]^_`{|}~

• Solution

– 12개의 문자 $( )*+.?[\^{| 를 제외한 문자들로 구성된 정규식은 그냥 대상 문자열에 있는 자

신과 똑같은 글자에 일치

– 정규식이 메타문자를 글자 그대로 대조하게 하려면 각 메타 문자 앞에 백슬러시를 넣어 메

타문자들을 이스케이프 처리 해야함

– ] 와 – 은 이스케이프 처리되지 않은 [ 뒤에 올 경우에만 메타문자로 인식

– } 는 이스케이프 처리되지 않은 { 뒤에 올 경우에만 메타문자로 인식

• 종료 괄호 ), }, ] 를 메타문자로 분류 X

The punctuation characters in the ASCII table are: !”#\$%&’\(\)\*\+,-\.\:;<=>\?@\[\\]\^_`{\|}~

정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

\$ \( \) \* \+ \. \? \[ \\ \^ \| $ ( ) * + . ? [ \ ^ | 일치

16

Page 17: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 리터럴 텍스트에 일치

• Variations

– 블록 이스케이프 <\Q>와 <\E>

• <\Q>는 백슬래시를 비롯해 <\E>까지의 모든 메타문자의 의미를 숨김

• <\E>를 사용하지 않을 경우 <\Q> 다음부터 정규식 끝까지의 모든 문자가 리터럴로 취

The punctuation characters in the ASCII table are: <\Q>!”#$%&’( )*+,-/:;<=>?@[\]^_`{|}~<\E>

정규식 스타일: PCRE, Perl, Java

17

Page 18: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 단어 채로 대조

• Problem

1) 대상 문자열이 “My cat is brown” 일 때, 이 문자열의 cat과는 일치되지만

category나 bobcat의 cat과는 일치되지 않는 정규식 작성

2) staccato의 cat과는 일치되지만 앞의 3개 대상 문자열의 cat과는 일치되지 않는

정규식 작성

• Solution

– 단어 경계

– 단어 비 경계

\bcat\b 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

\Bcat\B 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

18

Page 19: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 여러 문자 중 하나와 일치

• Problem

– 작성자가 ‘calendar’ 문자 검색 시 맞춤법에 틀리게 작성했을 가능성에 대비하여

문서 안의 오자까지 검색할 수 있도록 정규표현식 작성

• 흔히 발생하는 오자들과 일치되도록 작성: a, e를 사용할 수 있도록

• Solution

– 오자가 포함된 calendar

c[ae]l[ae]nd[ae]r 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

19

Page 20: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 여러 일치부를 그룹으로 묶어 캡처

• Problem

1) 일치를 완전한 단어로 한정해서 Mary나 Jane이나 Sue와 일치되게끔 정규식 작

• “Her name is Janet” 과 같은 문장일 경우 ‘Janet’과 일치 되면 안됨

2) yyyy-mm-dd 형식으로 된 모든 날짜와 일치된 후 년, 월, 일을 각각 캡처하는 정

규식 작성

• Solution

– 단어 일치

– 날짜 일치

\b(Mary|Jane|Sue)\b 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

\b(\d\d\d\d)-(\d\d)-(\d\d)\b 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

20

Page 21: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 여러 일치부를 그룹으로 묶어 캡처

• Variations

– 비 캡처 그룹

• 비 캡처 그룹의 그룹화 기능은 캡처 그룹과 똑같지만, 비 캡처 그룹은 아무것도 캡처하지 않음

• 캡처 그룹 수를 알아내기 위해 캡처 그룹의 시작 괄호를 셀 때, 비 캡처 그룹의 괄호는 제외

• 덕분에 번호가 매겨진 캡처 그룹 참조들을 엉망으로 만들기 않고 기존 정규식에 비 캡처 그룹을 넣을

수 있음

• 재참조부를 특정 그룹에 사용하지 않거나 치환 텍스트에 그 재참조부를 다시 삽입하거나 그 일치부를

소스코드 안으로 가져오는 경우에는, 캡처 그룹이 불필요한 오버헤드를 삽입하는데 비 캡처그룹을 사

용하면 오버헤드 제거

– 모드 변경자가 있는 그룹

• (?i) 대소문자 구분하지 않음

\b(?:Mary|Jane|Sue)\b 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

\b(?i:Mary|Jane|Sue)\b 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

21

Page 22: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 조건문으로 두 후보 중 하나 대조

• Problem

– 콤마로 구분돼 나열된 단어 one, two, three와 일치되는 정규식 작성

• 각 단어가 최소 한 번 이상 몇 번이든 들어있어도 일치돼야 함

• Solution

\b(?:(?:(one)|(two)|(three))(?:,|\b)){3,} 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python

22

Page 23: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 치환 텍스트에 정규식 일치부의 일부만 삽입

• Problem

1) 123467890처럼 이어지는 10자리 숫자에 일치되는 정규식 작성

2) 그 연속 숫자를 (123) 456-7890 같은 전화번호 형식으로 치환

• Solution

– 정규식

– 치환

\b(\d{3})(\d{3})(\d{4})\b

정규식 스타일: .NET, Java, PCRE, Perl, Python, Ruby

($1) $2-$3 정규식 스타일 : .NET, Java, JavaScript, PHP, Perl

(${1}) ${2}-${3} 정규식 스타일 : .NET, PHP, Perl

(\1) \2-\3 정규식 스타일 : PHP, Python, Ruby

23

Page 24: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 최소 반복 vs 최대 반복

• Problem

– XHTML 태그 <p>와 </p> 쌍과 그 사이의 텍스트에 일치되는 정규식 작성

• 두 태그 사이에 텍스트에는 다른 태그들이 들어있어도 일치 해야함

• 예.

<p> The very <em>first</em> task is to find the beginning of a paragraph. </p>

<p> Then you have to find the end of the paragraph </p>

• Solution

.* vs .*?

• 탐욕 정량자(greedy quantifier)

– <*>, <+>

– 제일 긴 유력 일치부를 우선적으로 검색

• 나태 정량자(lazy quantifier)

– <*?>, <+?>

– 제일 짧은 유력 대조부 검색

<p>.*?</p>

정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

24

Page 25: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 정규식에 주석 추가

• Problem

– \d{4}-\d{2}-\d{2} 정규식에 주석 추가

• Solution

– 공백무시 모드(free spacing)

• (?x)

• 해시(#) 기호가 문자 클래스 외부에서는 메타문자로 인식

• 해시는 행 끝이나 정규식 끝까지 실행되는 주석을 시작

(?x)\d{4} # Year - # Separator \d{2} # Month - # Separator \d{2} # Day

정규식 스타일: .NET, Java, PCRE, Perl, Python, Ruby

25

Page 26: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 유효성검사 – 이메일 주소

• Problem

– 이메일 주소의 유효 여부를 검사하는 정규식 작성

• Solution

– 이메일 메시지 형식 표준에서 허용하는 모든 문자 포함

– 접두 마침표, 접미 마침표, 연속 마침표가 없는지 검사

– 최상위 도메인이 단음문자 2~6개로 구성돼 있는지 검사

^[\w!#$%&'*+/=?`{|}~^-]+(?:\.[\w!#$%&'*+/=?`{|}~^-]+)*@↵ (?:[A-Z0-9-]+\.)+[A-Z]{2,6}$ 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python

26

Page 27: 정규표현식(Regular expressions)

Perl 호환 정규표현식 – 유효성검사 – 전체 텍스트에서 URL 검색

• Problem

– 긴 텍스트에서 URL을 찾아내는 정규식 작성

• 예. “http://www.somesite.com/page , where you will find more information” 일 때

URL 찾기

• Solution

\b((http?|ftp|file)://|(www|ftp)\.)[-A-Z0-9+&@#/%?=~_|$!:,.;]*↵ [A-Z0-9+&@#/%=~_|$] 정규식 스타일: .NET, Java, JavaScript, PCRE, Perl, Python, Ruby

27

Page 28: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식

28

Page 29: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식 - JAVA

• 프로그래밍 언어마다 정규표현식을 다르게 사용

JAVA에서 정규 표현식 사용 방법

– 정규식 라이브러리 불러오기

– 정규식 객체 생성

• 이미 알맞은 정규식임을 알고 있는 경우

• 정규식이 최종 사용자에 의해 입력되는 경우(UserInput은 문자열 변수)

• 문자열에 정규식을 사용하려면 Matcher를 생성

• 다른 문자열에 정규식을 사용하려면 위와 같이 새 Matcher을 생성하든지 다음과 같이 기존 Matcher

를 재사용

import java.util.regex.*;

Pattern regex = Pattern.compile("regex pattern");

try { Pattern regex = Pattern.compile(userInput); } catch (PatternSyntaxException ex) { // Syntax error in the regular expression }

Matcher regexMatcher = regex.matcher(subjectString);

regexMatcher.reset(anotherSubjectString);

29

Page 30: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식 - JAVA

JAVA에서 정규 표현식 사용 방법

– 정규식 옵션 지정

• 공백무시: Pattern.COMMENTS

• 대소문자 구분하지 않음: Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE

• 마침표는 개행문자와 일치: Pattern.DOTALL

• 캐릿과 달러는 개행문자 위치에서 일치: Pattern.MULTILINE

Pattern regex = Pattern.compile("regex pattern", Pattern.COMMENTS | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL | Pattern.MULTILINE);

30

Page 31: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식 – JAVA에서 정규식 사용

• 모든 일치부 가져오기

– 정규식이 각 일치부를 찾아낸 후 대상 문자열의 나머지 부분에 반복적으로 적용된다고 할

때, 그 정규식이 찾아낸 하위 문자열을 가져오기

• 예. “Please visit http://www.regexcookbook.com for more information” 문자열

• Matcher 클래스 메서드들

List<String> resultList = new ArrayList<String>(); Pattern regex = Pattern.compile(“http://([a-z0-9.-]+)"); Matcher regexMatcher = regex.matcher(subjectString); while (regexMatcher.find()) { resultList.add(regexMatcher.group()); }

find() 패턴이 일치하는 경우 true를 반환하고, 그 위치로 이동(여러개가 매칭되는 경우 반복 실행가능)

find(int start) start위치 이후부터 매칭검색을 수행

start() 매칭되는 문자열 시작위치 반환

start(int group) 지정된 그룹이 매칭되는 시작위치 반환

end() 매칭되는 문자열 끝 다음 문자위치 반환

end(int group) 지정되 그룹이 매칭되는 끝 다음 문자위치 반환

group() 매칭된 부분을 반환

group(int group) 매칭된 부분중 group번 그룹핑 매칭부분 반환

groupCount() 패턴내 그룹핑한(괄호지정) 전체 갯수 반환

matches() 패턴이 전체 문자열과 일치할 경우 true 반환

Please visit http://www.regexcookbook.com for more information

Please visit http://www.regexcookbook.com for more information

http://www.regexcookbook.com

31

Page 32: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식 – JAVA에서 정규식 사용

• 모든 일치부 치환

– 정규식 before 의 모든 일치부를 치환 텍스트 after로 치환

– 대상 문자열 검색치환

– 치환 시 예외 클래스

String resultString = null; try { Pattern regex = Pattern.compile("before"); Matcher regexMatcher = regex.matcher(subjectString); try { resultString = regexMatcher.replaceAll("after"); } catch (IllegalArgumentException ex) { // Syntax error in the replacement text (unescaped $ signs?) } catch (IndexOutOfBoundsException ex) { // Non-existent backreference used the replacement text } } catch (PatternSyntaxException ex) { // Syntax error in the regular expression }

약기 함수 정규 표현

replaceFirst() Pettern.compile(“before”).matcher(subjectString).replaceFirst(“after”)

replaceAll() Pattern.compile(“before”).matcher(subjectString).replaceAll(“after”)

Exception Reason

IllegalArgumentException

치환 텍스트 문법 에러 replaceFirst() / repalceAll()

IndexOutOfBoundsException 치환 텍스트가 문법적으로 올바른데 존재하지 않는 캡처 그룹 참조

PatternSyntaxException 정규식 문법 에러 Pattern.compile() / String.replaceFirst() / String.replaceAll()

32

Page 33: 정규표현식(Regular expressions)

프로그래밍을 위한 정규표현식 – JAVA에서 정규식 사용

• 절차 코드 안의 일치부 유효검사

– 정규식 안에 간단히 삽입할 수 없는 특정 부가 조건에 부합하는 일치부들을 가져오기

• 예. 로또 번호들을 가져온다면 13의 정수 배수인 번호들을 계속 보관

List<String> resultList = new ArrayList<String>(); Pattern regex = Pattern.compile("\\d+"); Matcher regexMatcher = regex.matcher(subjectString); while (regexMatcher.find()) { if (Integer.parseInt(regexMatcher.group()) % 13 == 0) { resultList.add(regexMatcher.group()); } }

33

Page 34: 정규표현식(Regular expressions)

Regular Expression Reference

34

Page 35: 정규표현식(Regular expressions)

Regular Expression Reference – Meta문자

• 정규표현식에서 사용하는 기호

– Meta문자: 표현식 내부에서 특정한 의미를 갖는 문자

• 공통적인 기본 Meta문자 종류

x{n,m} 35

Page 36: 정규표현식(Regular expressions)

Regular Expression Reference – Meta문자

• 문자클래스’[ ]’ (character class)

– 문자 클래스, "["와 "]" 사이에 포함된 문자 집합 내부에 해당하는 문자열의 범위

중 한 문자열만 선택

• [ ] 안에서 모든 문자는 각각 하나의 문자를 의미

– 문자클래스 내부에서는 Meta문자를 사용할 수 없거나 의미가 다르게 사용

• 특수기능: \, ^, -, ]

• 그 외에 문자들은 순수한 리터럴 문자로 인식

[\^]

36

Page 37: 정규표현식(Regular expressions)

Regular Expression Reference – Character Shorthands

• 단축 문자(Character Shorthands)

37

Page 38: 정규표현식(Regular expressions)

Regular Expression Reference – POSIX 문자클래스

• POSIX 에서만 사용하는 문자 클래스

38

Page 39: 정규표현식(Regular expressions)

참고서적

39

• 처음 시작하는 정규표현식(introducing regular expressions)

• 한 권으로 끝내는 정규표현식(regular expressions cookbook 2nd edition)