티스토리 뷰

이번에는 패턴을 입력의 어느 부분에 대해 매치할 것인가를 지정하는 방법을 알아봅시다. 정규표현식에서는 위치의 개념이 시작, 끝, 단어 경계 등 여러 가지가 있습니다. 물론 각각이 아닌 경우도 조건으로 표현할 수 있겠지요.

경계를 지정하는 기호들은 다음과 같습니다.

경계 요소 설명
^ 한 줄의 시작부
$ 한 줄의 끝
\b 단어 경계
\B 단어 경계가 아닌 곳
\A 입력의 시작부
\G 직전 매치의 끝
\Z 마지막 종료문자가 아닌 입력의 끝
\z 입력의 끝

이렇게 다양한 경계 매처를 어떻게 이용할 수 있을까요? 한 가지씩 살펴보겠습니다.


(1) 입력 시작부에서만 매치하기

패턴 앞에다 ^을 넣으면 입력의 시작 부분에서 한번만 매치하라는 뜻이 됩니다. 입력 중간에 매치되는 부분이 있어도 무시하게 됩니다.

 

(2) 입력의 끝에서만 매치하기

패턴 뒤에 $를 넣으면 입력의 끝에서만 매치하라는 뜻이 됩니다. 이 경우는 앞이나 중간에 매치되는 것이 있더라도 무시하고 제일 끝에 있는 것에 매치되는 부분만 찾습니다. 정규표현식 테스트 프로그램

(1) regex 먼저    (2) input 먼저   (3) 그룹찾기   (기타) 종료.. 1

regex: ^a*b*
input: aabbababccab
찾은 문자열  "aabb" (0, 4)
input: bbbbaabbb
찾은 문자열  "bbbb" (0, 4)
input: aaaaccaabbcc
찾은 문자열  "aaaa" (0, 4)
input: ccaabbcc
찾은 문자열  "" (0, 0)
input: 

위 예제에서 a*b*에 대해 제일 앞에서 한번만 매치하는 것을 볼 수 있습니다. 마지막 입력은 길이 0인 문자열에 매치되었습니다. *는 0번 반복도 포함하므로... (greedy여서 최대한 매치하려고 하니까 앞에서는 길이 0인 문자열은 매치되지 않았습니다)

다음 예제에서는 끝에 매치되는 패턴을 보여줍니다.

(1) regex 먼저    (2) input 먼저   (3) 그룹찾기   (기타) 종료.. 1

regex: \d+$
input: abcd0123a1234
찾은 문자열  "1234" (9, 13)
input: 1234a567890
찾은 문자열  "567890" (5, 11)
input: 5678.123
찾은 문자열  "123" (5, 8)
input: 5678.
No match found.
input: 

 예제에서는 끝에 오는 숫자(길이 1이상)만 매치합니다. 끝에서부터 숫자인 것을 최대한 찾아주는 매치입니다. 숫자가 아닌 것 앞에 나오는 숫자 부분은 끝이 아니므로 무시합니다. 또 마지막 입력처럼 끝에 숫자 아닌 것이 나오면 매치되지 않습니다.

(3) 전체 입력에 대해 매치하기

regex: ^\d+$
input: 1234-5678
No match found.
input: 12345678
찾은 문자열  "12345678" (0, 8)
input: (12345678)
No match found.
input: 

패턴이 ^로 시작하고 $로 끝나면 입력 전체에 대해 매치하라는 뜻입니다. 이 예제에서는 숫자로만 이루어진 입력인지 검사하는 것이 되겠지요?

(4) 단어 단위로 매치하기

단어는 영문자, 숫자, 밑줄로 이루어진 입력의 부분입니다(밑줄로 시작은 안됨). 이런 문자가 아닌 글자로 나누어진 최대 입력문자열 부분을 뜻합니다. 단어 단위가 매치되게 하기 위해서는 \b를 이용해서 경계를 표시하게 됩니다. 이것은 단어 전체가 패턴에 매치되는 경우만 찾게 됩니다. 

(1) regex 먼저    (2) input 먼저   (3) 그룹찾기   (기타) 종료.. 1

regex: \b\w+\b
input: hello my name is djksl!!
찾은 문자열  "hello" (0, 5)
찾은 문자열  "my" (6, 8)
찾은 문자열  "name" (9, 13)
찾은 문자열  "is" (14, 16)
찾은 문자열  "djksl" (17, 22)
input: this is a __word match__ test~~ !!
찾은 문자열  "this" (0, 4)
찾은 문자열  "is" (5, 7)
찾은 문자열  "a" (8, 9)
찾은 문자열  "word" (10, 14)
찾은 문자열  "match__" (15, 22)
찾은 문자열  "test" (23, 27)
input: 123 .\^$ a567 a^^&&
찾은 문자열  "123" (0, 3)
찾은 문자열  "a567" (9, 13)
찾은 문자열  "a" (14, 15)
input:

\b와 \b로 둘러싸서 패턴을 단어 단위로 매치시키고 있습니다. 여기서 \w는 이름 글자 즉 영문자, 숫자, 밑줄을 나타내는 문자 부류(character class)입니다. 위 예에서 특수문자는 매치되지 않는 것을 볼 수 있습니다. 그리고 공백과 단어 아닌 것들을 \b로 구분해 주는 것을 알 수 있습니다.  여기서 한가지 헷갈리는 것은 _word에서 word만 매치시켰다는 것입니다. 밑줄로 시작은 안된다는 조건 때문에 밑줄은 단어 중간에 나올 때는 \w로 매치되지만 제일 앞에 나오는 것은 단어 경계로 인식됨을 알 수 있습니다.

(1) regex 먼저    (2) input 먼저   (3) 그룹찾기   (기타) 종료.. 1

regex: \b\d+\b
input: abc1234
No match found.
input: 1234abc abc 789 a5678 _789.00
찾은 문자열  "789" (12, 15)
찾은 문자열  "00" (27, 29)
input: 

이 예제에서는 단어 전체가 숫자인 것만 찾습니다. 즉 영문자가 섞이지 않은 숫자로만 되어 있는 부분을 찾는 것이지요. 

경계 매처에서 ^와 \A의 구분에 대해 확인해 두어야 할 것이 있습니다. 정규표현식은 줄바꿈에 대해서는 좀 특별하게 취급을 합니다. 즉 여러 줄을 입력으로 받을 것인지 여부에 따라 엔터 키가 그냥 문자가 되기도 하고 입력의 끝이 되기도 합니다. 이러한 차이 때문에 한줄만 입력 받을 때는 두 가지가 똑같은 의미가 되지만 설정에 의해 여러 줄입력이 가능한 경우라면 \A는 입력의 시작, ^는 한 줄의 시작을 의미하게 됩니다. $와 \Z도 같은 역할을 합니다.

경계매처를 이용해서 입력에 대해 특정 부분에 매치하는 방법을 알아보았습니다. 

줄의 시작과 끝, 또는 단어의 시작과 끝을 표현할 수 있음을 보았는데요, 이것은 언어마다 약간씩 달라지고 설정에 따라서도 달라질 수 있는 것이므로 사용하는 언어와 환경에서 다시 확인해 보실 필요가 있습니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함