정규식 Regular Expression 기초 2/3

글쓴이 Engineer Myoa 날짜

정규식 Regular Expression 기초 2/3

문자집합까지 끝을 냈고 이번에는 OR연산 그리고 수량자(*, ?, +)에 대해 알아보겠습니다.

소괄호안에 |(Shift + \키) 를 넣으면 정규식에서의 OR연산이 됩니다.

“월요일 화요일 수요일 목요일 금요일 토요일 일요일”에서

(토|일)요일 로 검색하면 [“토요일”, “일요일”]이 매칭됩니다.

11.

수량자에 들어가기 앞서 수량자는 크게 *, +, ? 3개로 나눌 수 있습니다.

*는 없거나 무한에 가까울때까지 검색,

+는 무조건 1개이상 이며 무한에 가까울때까지 검색,

?는 앞의 문자가 있거나 없거나 (한글자만) 검색을 하게 됩니다.

쉽게 정리하자면

*는 앞문자를 x번 검색합니다. ( 0 <= x )

+는 앞문자를 x번 검색합니다. ( 1 <= x )

?는 앞문자를 x번 검색합니다. ( 0 <= x <= 1 )

12.

수량자 *에 대한 예들입니다.

아무개문자 . 와 수량자 *가 만나

문장전체가 하나의 매치로 발견되었습니다.

13.

수량자 +에 대한 예들입니다.

수량자 +를 이해하기에 적절한 예시가 없어보여 새로운 예시를 들어보겠습니다.

“나는 사과를 2개 먹었다.” 에서

[0-9]+개 먹었다. 라는 식으로 검색하면

[“2개 먹었다.”] 가 검색됩니다.

“나는 사과를 15개 먹었다.” 많이도 먹었군요.

이 문장에서 같은 [0-9]+개 먹었다. 식으로 검색하면

[“15개 먹었다.”] 가 검색됩니다.

하지만

“나는 사과를 one개 먹었다.” 라는 식에서

[0-9]+개 먹었다. 식으로 검색하면

아무것도 발견되지 않습니다.

왜냐하면 “개 먹었다” 앞에 숫자가 1개 이상 오라고 식을 작성했기 때문이죠.

따라서 +는 최소한 해당 문자를 1개 이상 포함해야만 검색이됩니다.

14.

수량자 ?에 대한 예들입니다. 아까보다 더 적절하지 못하네요

마찬가지로 새로운 예시를 들어보겠습니다.

“게임을 하고싶다” 라는 문장과

“게임을 더 하고싶다” 라는 문장 2개가 있습니다.

어떻게 하면 두 문장 다 매치가 될까요?

“더? ”를 ?연산자로 넣으면됩니다. 물론 눈치가 빠르신 분들은 알아차리셨겠지만 *로 동작합니다.

“게임을 더? ?하고싶다” 라는 식은 분명히 “더”라는게 들어갔지만 두 문장다 이상없이 매치가 됩니다.

바로 수량자 ? 덕분에 “더”라는 글자가 들어가도 되고, 들어가지 않아도 되기 때문입니다.

여기서 한가지 보기 싫은부분은 “더? ?”죠. 우리는 더 ?를 원했지만 정규식을 이를 허가하지 않습니다.

따로따로 더가 있거나 없고, 공백이 있거나 없거나로 식을줘야만이 위 문장에서 정상적으로 검색이 가능합니다.

이에 대해 추후 나올 subexpression(하위식)에 해답이 있는데

(더 )?” 라고 식을주면 “더? ?” 와 같은 동작을 하고 이에 조금나아가 “(더 ?)?”로 작성을 한다면

“게임을 하고싶다”

“게임을 더하고싶다”

“게임을 더 하고싶다”

모두 매치가 됩니다 🙂

http://myoa.kro.kr/” 라는 주소 문자열에서

https?:\/+w*\.?myoa\.kro\.kr 라는식으로 검색해봅시다.

하나씩 분석해보자면(보기좋게 자르자면)

http s? \/+ w*\.? myoa\.kro\.kr 입니다.

http : 말 그대로 http를 검색합니다.

s? : s 한글자가 있거나 없거나(1개이거나 0개)를 검색합니다.

\/+ : \/(/를 이스케이핑한 것)가 1개이상을 검색합니다.

w*\.? : w가 없거나 또는 여러개거나 그리고 “.”이 있거나 없거나를 검색합니다.

myoa\.kro\.kr : 그리고 마지막으로 메인주소인 “myoa.kro.kr”를 검색합니다.

이 정규식이 찾아 낼 수 있는 주소는 아래와 같습니다.

http://myoa.kro.kr

https://myoa.kro.kr

http://www.myoa.kro.kr

https://www.myoa.kro.kr

갑자기 장황한 식이 나와서 당황할 수 있으나 하나씩 차근차근 곱씹어 보시고, 모르는 것은 질문바랍니다.

15.

다음은 지정 수량자입니다. 사실 지정이라고 부르지는 않지만 의미상 편하게 부르기 위해 지정해봤습니다.

해선 안될 짓중 하나이긴 한데.. 너무 모호해서

수량자 ?는 너무적고 수량자 *는 너무 많다. 싶으면 브레이스( { } )를 이용합니다.

이는 수량을 직접 조절할 수 있으며 가독성에 좀 더 도움이 될 수도 있죠.

사용식은 {x,y}이며 x > y여야 합니다. 강력한 주의사항은 절대로. 절대로 {}안에 공백을 넣어서는 안됩니다.

또한 x나 y를 생략가능하며 문자 하나를 생략하여 단항일 경우 0은 제외하고 사용해야합니다. (infinity loop에 걸림)

{1} : 1개

{2,6} : 2개 이상 6개이하

{5,} : 5개 이상

{,6} : 6개 이하

가장 간단하게 .{5} 라는 식은 아무 문자나 5개를 찾는다 입니다.

따라서 [“One r”]이 첫 번째로 매치가 됐고 그 뒤를 이어서 [“ing t”, “o bri”…….]가 매치가 됩니다.

[els]{1,3} 식은 “e”, “l”, “s”중에 1~3번 반복된 부분을 찾는다 입니다.

그래서 e도 찾아지고 ll, ess가 찾아지는겁니다.

간단하죠?

16.

이번에는 수량자 *, +, ?와 수량자 { }의 상관관계를 배워보겠습니다.

15번을 잘 보신분이라면 각 수량자를 수량자{ }로 표현이 가능하다는 것을 눈치챘을텐데요,

* == {0,} #단항이 아니라 0이 올 수 있습니다.

+ == {1,}

? == {0,1}

위에 예시 또한 같은 의미를 담고있습니다.

하지만 보통의 경우 가독성을 위해 수량자 *, +, ?를 주로사용하며 특정 개수일때만 수량자 {}로 지정해서 사용한답니다.

17.

이번에는 수량자의 특별기능입니다.

“하늘과 땅과 바람과 물과” 라는 문장에서

~~과 들을 추출하려고 합니다.

지금까지 배운바로는 .+과 또는 .*과(추천하지 않음)를 사용할텐데

그렇게 호락호락하게 원하는 결과를 내어주지 않습니다.

왜냐하면 위에 식의 결과는 다음과 같기 때문입니다.

[“하늘과 땅과 바람과 물과”]

왜 그럴까요?

정규식 수량자에는 크게 탐욕적 수량자(Greedy quantifier)게으른 수량자(Lazy quantifier)로 나뉩니다.

기본적으로 수량자를 사용할때는 탐욕적 수량자로 동작합니다. 하지만 수량자 뒤에 ?를 붙이면 게으른 수량자로 바뀌어 동작합니다.

탐욕적 수량자 : 최대한 넓은 범위를 매치시키려고 합니다.

게으른 수량자 : 최대한 좁은 범위를 매치시키려고 합니다.

.+?과를 사용해볼까요?

[“하늘과”, “땅과”, “바람과”, “물과”]

하나씩 차근차근 생각해보죠.

.+과

.는 아무 문자를 의미합니다.

맨처음 “하”가 매치되겠죠? 거기서부터 + 즉 1개이상의 아무문자를 잡습니다.

언제까지? 로 끝날때까지

늘과 땅과 바람과 물

합쳐서 [“하늘과 땅과 바람과 물과”]가 매치됩니다.

한 마디로 가장 크게잡는거죠 .+ 의 범위를

하지만 .+?과는 아까 말한것처럼 가장 좁은 범위를 매치시키려고 합니다.

.는 아무 문자를 의미합니다.

역시 맨처음 “하”가 매치됩니다. 거기서부터 +. 1개 이상의 아무문자를 잡습니다.

가 나올때까지

중요한부분은 나올때까지입니다.

——

——

…..

합쳐서 [“하늘과”, “땅과”, “바람과”, “물과”] 총 4개의 그룹으로 매치됩니다.

그렇다면

r.?? 식은 어떻게 해석될까요?

r 그리고 아무문자(.)인데 있어도 되고 없어도(0 or 1) 됩니다. 근데 최소로(?) 잡겠답니다.

당연히 최소로 잡으려면 아무문자가 0개여야하겠죠?

그래서 결과적으로 이식은 r 단일문자만 매치하게됩니다.

마지막 탐욕적 수량자랑 게으른 수량자를 너무 장황하게 설명했는데 수량자는 잘못이해하고 잘못사용하면 infinity loop에 빠지는건 둘째문제이고 논리적 오류가 어디서 발생했는지 못찾아서 골때리는 경우가 허다합니다.

따라서 수량자를 적절하고 잘 사용하고 다음에 배울 하위식(subexpression)과 적절히 조합한다면 자신에게 필요한 정규식이 완성될 것입니다.

기초 2/3편을 마치겠습니다. 수고하셨습니다.

카테고리: 강의

3개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다