본문 바로가기

손에 잡히는 정규 표현식

페이지 수가 작아 들고 다니면서 보기도 좋고, 내용도 알찬 책인 거 같다. 

  

https://blog.insightbook.co.kr/2009/07/23/%EC%86%90%EC%97%90-%EC%9E%A1%ED%9E%88%EB%8A%94-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D/

 

손에 잡히는 정규 표현식

프로그래밍을 하고 있다면 반드시 들어봤을 단어가 있습니다. 바로 정규 표현식이지요. 언어를 다루는 어떤 서적을 보더라도 정규 표현식에 대해 일정 분량을 할애하여 설명하고 있음을 알 수 �

blog.insightbook.co.kr

 

메타문자 사용하기

 

  • 공백메타문자
메타 문자 설명
[\b] 역스페이스
\f 페이지 넘김(form feed)
\n 줄바꿈
\t
\v 수직탭

 

  • 숫자, 영숫자, 공백 메타문자
구분 메타문자 설명
숫자 \d 숫자 하나([0-9]와 같다.)
숫자 \D 숫자를 제외한 문자 하나([^0-9]와 같다 
영숫자 \w 대소문자와 밑줄을 포함하는 모든 영숫자([a-zA-Z0-9_]와 같다.)
영숫자 \W 영숫자나, 밑줄이 아닌 모든문자([^a-zA-Z0-9_] 와 같다.)
공백 \s 모든 공백문자([\f\n\r\t\v] 와 같다.)
공백 \S 공백문자가 아닌 모든문자([^\f\n\r\t\v] 와 같다.)

 

  • 포직스 문자 클래스 
분류 내용
[:alnum:] 모든 영숫자([a-zA-Z0-9_]와 같다.)
[:alpha:] 모든 영문자([a-zA-Z]와 같다.)
[:blank:] 빈칸(space)이나 탭 문자([ \t]와 같다.)
[:cntrl:] 아스키 제어문자(아스키 0번부터 31, 127번)
[:digit:] 모든 한자리 숫자([0-9]와 같다.)
[:graph:] [:print:]와 동일하나 빈칸(space)는 제외
[:lower:] 모든 소문자([a-z]와 같다.)
[:print:] 출력가능한 모든 문자
[:punct:] [:alnum:]이나 [:cntrl:]가 포함되지 않은 모든문자
[:space:] 빈칸을 포함한 모든 공백문자([\f\n\r\t\v] 와 같다.)
[:upper:] 모든 대문자([A-Z]와 같다.)
[:xdigit:] 모든 16진수 숫자([a-fA-F0-9]와 같다.)

 

반복찾기

  • 탐욕적 수량자, 게으른 수량자
탐욕적 수량자 게으른 수량자
* *?
+ +?
{n,} {n,}?

 

위치찾기

단어경계 설명 사용 예문
\b 단어의 시작이나 마지막을 일치시킬 때 사용 \bcat\b The cat scattered his food all over the room
\bcap The captain owre this cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.
\bcat\b

my cat is cute. (일치)

 

He is scattering his money about. (일치하지 않음)

\B 단어 경계와 일치시키고 싶지 않을 때 사용 \B-\B Please enter the nine-digit id as it appears on your color - coded pass-key.
\Bcat\B

my cat is cute. (일치하지 않음)

 

He is scattering his money about. (일치)

\B-\B는 단어 구분(word-break) 문자로 둘러싸인 하이픈과 일치한다. 그러므로 nine-digit와 pass-key에 있는 하이픈은 일치하지 않지만 , color - coded에 있는 하이픈과는 일치한다. 

 

표현 설명 사용
^ 문자열의 시작 ^\s<\?xml.*\?>
$ 문자열의 끝 </[Hh][Tt][Mm][Ll]>\s*.$
(?m) 다중행 모드 (?m)^\s*//.*$

 

하위 표현식 사용하기

사용 설명 예문
19|20\d{2} 19 혹은 20\d{2}를 나타냄 DOB: 1967-08-07
(19|20)\d{2} 19\d{2} 혹은 20\d{2}를 나타냄 DOB: 1967-08-17
(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))

모든 한 자리 혹은 두자리 숫자

1로 시작하는 모든 세자리 숫자

2로 시작하면서 두 번째 두 번째 자리 숫자가 0부터 4사이의 모든 세자리 숫자

25로 시작하면서 세번째 자리 숫자가 0부터 5사이의 모든 세자리 숫자

 

Pinging hog.forta.com [12.159.46.200]

industr(?:y|ies)

industry|industries

패턴의 일부를 "or" 문자(|를 사용하여 결합할때 유용)

industry

industies

industr

 

역참조 사용하기

사용 예문
[ ]+(\w+)[ ]+\1 This is a block of of text, several words here are are repeated, and and they should not be.
<[Hh]([1-6])>*.?</[Hh]\1>

<H1>Welcome to my Homepage</H1>

<H2>This is not valid HTML</H3>

예문 정규표현식 치환 결과
Hell, ben@fortra.com is my email address. (\w+)[\w\.]*@[\w\.]+\.\w+ <A HREF="mailto:$1">$1</A> Hello, <A HREF="mailto:ben@fortra.com">ben@fortra.com</A> is my email address.

313-555-1234

248-555-9999

810-555-9000

(\d{3})(-)(\d{3})(-)(\d{4}) ($1) $3-$5

(313) 555-1234

(248) 555-9999

(810) 555-9000

  • 대소문자 변환 메타문자
메타문자 설명
\E \L 혹은 \U의 변환 끝을 나타낸다.
\I 다음에 오는 글자를 소문자로 변환한다.
\L \E를 만날 때까지 모든 문자를 소문자로 변환한다.
\u 다음에 오는 글자를 대문자로 변환한다.
\U \E를 만날 때까지 모든 문자를 대문자로 변환한다.
예문 정규표현식 치환 결과
<H1>Welcome to my Homepage</H1> (<[Hh]1>)(*.?)(</[Hh]1>) $1\U$2\E$3 <H1>WELCOME TO MY HOMEPAGE</H1>
(<[Hh]1>)(*.?)(</[Hh]1>)패턴은 헤더를 시작태그, 텍스트, 종료태그 이렇게 세 부분으로 나눈다. 두번째 패턴은 이 텍스트 들을 다시 합치는데 $1 시작태그와 일치하고, \U$2\E는 헤더 텍스트인 두번째 하위 표현식과 일치한 다음 이 텍스트를 대문자로 변환하며, $3은 종료태그와 일치한다.

 

전방탐색과 후방탐색

 

  • 전후방 탐색 명령
종류 설명
(?=) 긍정형 전방탐색
(?!) 부정형 전방탐색
(?<=) 긍정형 후방탐색
(?<!) 부정형 후방탐색
구분 정규표현식 예문
전방탐색-앞으로 찾기 .+(?=:) http://www.forta.com/

https://mail.forta.com/

ftp://ftp.forta.com/

 

후방탐색-뒤로 찾기 (?<=\$)[0-9]+

ABC01: $23.45

HGG42: $5.31

CFMX1: $899.00

XTC99: $69.96

전방탐색-후방탐색 함께 사용하기 (?<=<[tT][iI][tT][lL][eE]>).*(?=</[tT][iI][tT][lL][eE]>) <TITLE>Ben Forta's Homepage</TITLE>
부정형 전후방탐색 \b(?<!\W$)\d+\b I paid $30 for 100 apples, 50 oranges, and 60 pears, I saved $5 on this order.
(?<=\$)\d+ I paid $30 for 100 apples, 50 oranges, and 60 pears, I saved $5 on this order.
(?<!\$)\d+ I paid $30 for 100 apples, 50 oranges, and 60 pears, I saved $5 on this order.
부정형 전후방 탐색에서 단어경계가 없으면, $30에 있는 0도 일치한다. 숫자 0앞에 $기호가 없기 때문이다. 전체 패턴을 단어경계로 감싸 이 문제를 해결했다.

 

  • 순환반복을 지정하기 위한 그룹 지정 정규식
예제 결과 설명
(?=.*jsp)(?=.*php)

page jsp php 패턴일치

php jsp page 패턴일치

page page    패턴불일치

정규표현식을 입력값의 시작위치에서부터 검색한다. 이 패턴이 반복 나열된 경우 패턴이 일치하면 다음 패턴을 검색한다.

일치는 하지만 매칭되는 size는 0이다.

(?!.*jsp)(?!.*php)

page jsp php 패턴불일치

php jsp page 패턴불일치

page page    패턴일치

정규식패턴을 입력값의 시작위치에서부터 검색한다. 이 패턴이 반복 나열된 경우 패턴이 일치하지 않으면 다음 패턴을 검색한다.

일치는 하지만 매칭되는 size는 0이다.

 

 

조건 달기

 

  • 역참조 조건
정규표현식 결과
(<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa]>)

<!-- Nav bar -->

<TD>

<A HREF="/home"><IMG SRC="/images/home.gif"></A>

<IMG SRC="/images/spacer.gif">

<A HREF="/home"><IMG SRC="/images/home.gif"></A>

<IMG SRC="/images/spacer.gif">

<A HREF="/home"><IMG SRC="/images/home.gif"></A>

</TD>

(?(1)\s*</[Aa]>)는 조건으로 시작하는데, ?(1)은 역참조1(<A> 시작태그)이 있을때만 수행하라는 말이다. 다른말로 <A>태그와 일치한다면 그 뒤의 종료태그도 일치시키라는 뜻이다. 만약(1)이 있다면, \s*</[Aa]>는 </A>가 나오기 전까지 모든 문자를 일치영역에 넣어준다.
^(\()?\d{3}(?(1)\|-)\d{3}-\d{4}

123-456-7890

(123)456-7890

(123)-456-7890

(123-456-7890

1234567890

123 456 7890

(?(1)\|-)는 조건을  만족하는지에 따라 닫는 괄호()) 혹은 하이픈(-)과 일치한다. 만약 (1)이 있다면(다시말해 여는 괄호가 있다면), \)와 일치하고, 없다면 하이픈(-)과 일치한다. 이런식으로 괄호가 항상 짝을 이룰 수 있고, 지역번호와 숫자를 구분하는 하이픈 괄호가 없을 때만 일치한다.

 

  • 전후방탐색 조건
구분 정규표현식 결과
일반 탐색조건 \d{5}(-\d{4})?

11111

22222

33333-

44444-4444

전 후방 탐색조건 \d{5}(?(?=-)-\d{4})

11111

22222

33333-

44444-4444

\d{5}는 앞부분에 있는 다섯자리 숫자와 일치한다. 그러고 나서 (?(?=-)-\d{4})같은 형태를 한 조건이 나타난다. 이 조건은 전방탐색 ?=-를 써 하이픈을 찾아내지만 소비하지는 않는다ㅏ. 그리고 하이픈이 있다는 조건을 마족하면, -\d{4}는 그 하이픈과 이어 나오는 숫자 네개와 일치한다. 이 방법을 쓰면 33333-은 일치하지 않는다. 하이픈이 있어서 조건은 만족하지만, 뒤에 숫자 네개가 이어지지 않기 때문이다.

 

정규표현식을 이용한 패스워드 설정 정책 예시

  • 패스워드 설정 정책은 한국 인터넷진흥원 '암호 정책 수립 기준 설명서'에 포함되어 있는 안전한 패스워드 정책 적용
문자구성 및 길이조건 세가지 종류 이상의 문자구성으로 8자리 이상 길이로 구성
두가지 종류 이상의 문자 구성으로 10자리 이상 길이로 구성
문자종류는 알파벳 대문자/소문자, 숫자, 특수문자로 구분
특정정보이용 및 패턴조건 한글, 영어등의 사전적 단어를 포함하지 않음
널리 알려진 단어를 포함하지 않거나 예측이 어렵도록 가공
사용자 ID와 연관성이 있는 단어를 포함하지 않음
제3자가 쉽게 알수 있는 개인 정보를 포함하지 않음
기타조건 이전에 사용하던 패스워드와 연관성이 없는 단어로 구성
  • 패스워드 정책에 맞는 정규표현식
정규표현식 설명
^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=\-])(?=.*[0-9]).{8,20}$ 패스워드 정책은 알파벳, 숫자, 특수문자를 조합하여 8글자 이상 20자 이하로 설정한다.
(?=.*[a-zA-Z]) 하나이상의 알파벳을 포함한다.
(?=.*[0-9!@#$%^*+=\-]) 하나 이상의 숫자나 특수문자를 포함한다.
{8,} 최소글자 8글자 이상이어야 한다.

 

'' 카테고리의 다른 글

손에 잡히는 Vim  (0) 2020.04.23