References
- Learning Regular Expressions
Contents
- 여러 문자 중 하나와 일치시키기
- 문자 집합 범위 사용하기
- '제외하고' 찾기
지난 포스팅에서 어떤 문자와도 일치하는 마침표(.)에 대해서 배웠습니다.
이번 포스팅에서는 문자 집합을 사용해서 특정 문자들과 문자 범위에 대해 일치시킬 수 있는 방법에 대해 알아보겠습니다.
여러 문자 중 하나의 일치시키기
마침표(.)는 어떤 문자든지 문자 하나와 일치합니다. 이전 포스팅 마지막 예제에서 na와 sa를 찾기 위해 '.a' 패턴을 사용햇습니다. 하지만 만약 ca1.xls와 같은 파일이 있을 때, na와 sa만을 찾고 싶을 때는 어떻게 해야 할까요? '.a' 패턴을 그대로 사용하면 ca1.xls라는 파일명도 이 패턴에 해당하므로 여기서 마침표는 'c'와도 일치할 것입니다.
sales1.xls
orders3.xls
sales2.xls
sales3.xls
apac1.xls
europe2.xls
na1.xls
na2.xls
sa1.xls
ca1.xls
아래 결과는 '.a.\.xls' 패턴에 대한 결과입니다.
모든 문자가 아니라 n이나 s와 일치하는 파일명만 찾고 싶을 때, 정규표현식에서는 메타 문자인 대괄호([])를 사용해 문자 집합을 표현합니다. 대괄호는 문자 집합을 정의합니다. 대괄호 안에 있는 문자는 모두 집합의 구성원이 되며, 집합에 속한 문자 가운데 하나가 일치하게 됩니다. 즉, 집합에 속한 문자가 모두 일치할 필요는 없습니다.
따라서 위에서 사용한 패턴을 수정하여, '[ns]a.\.xls'를 사용하면 다음의 결과를 얻을 수 있습니다.
여기서 사용한 정규표현식은 [ns]로 시작합니다. 이 패턴은 n이나 s 중 한 문자와 일치하며, c나 다른 문자와는 일치하지 않습니다. 대괄호는 집합을 의미하므로 대괄호 자체([])는 어떤 문자와도 일치하지 않습니다. 문자 a는 a와 일치하고 마침표(.)는 모든 문자와 일치합니다. '\.'는 마침표 자체와 일치하고 xls는 문자 그대로 xls와 일치합니다. 따라서 '[ns]a.\.xls' 패턴을 사용하면 찾으려던 3개의 파일명만을 찾을 수 있습니다.
다만, 실제로 이런 상황에서 이 정규표현식도 정답은 아닙니다. 만약 파일명 가운데 usa1.xls가 있다면, 이 파일명 역시 위의 정규표현식과 일치하지 때문입니다. 이 문제를 해결하려면 위치도 지정해서 찾아야 하는데, 이는 다른 포스팅에서 다르도록 하겠습니다.
문자 집합은 흔히 대소문자를 구별하지 않고 검색하거나 검색할 부분의 특정 영역만 대소문자를 구별하지 않을 때 사용합니다. 다음 예제를 살펴보겠습니다.
The phrase "regular expression" is often
abbreviated as RegEx or regex.
위 예문에 정규표현식 '[Rr]eg[Ee]x' 패턴과 일치하는 것을 찾으면 결과는 다음과 같습니다.
여기서 사용한 패턴에는 문자 집합이 2개가 있습니다. [Rr]은 R이나 r과 일치하고, [Ee]는 E나 e와 일치합니다. 이런식으로 RegEx와 regex 둘 다 일치시킬 수 있습니다. 하지만, REGEX와는 일치하지 않습니다.
만약, 대소문자를 구별하지 않고 모든 문자를 찾아도 된다면, 이러한 기법은 필요하지 않습니다. 이런 식의 검색은 부분적으로 대소문자를 구별하지 않을 때만 사용합니다.
문자 집합 범위 사용하기
다시 파일 목록 예제로 돌아가서 살펴보도록 하겠습니다. 위에서 사용한 패턴 '[ns]a.\.xls'에는 또 다른 문제가 있습니다. 만약 sam.xls라는 파일이 있다면 어떻게 할까요? 마침표(.)는 숫자뿐만 아니라 모든 문자와도 일치하므로 sam.xls라는 파일명과도 일치합니다.
이러한 문제는 문자 집합을 사용하여, 다음의 정규표현식으로 해결할 수 있습니다.
'[ns]a[0123456789]\.xls'
여기서 사용한 정규표현식에서는 첫 글자가 n이나 s와 일치하고, 두 번째 글자는 a, 세 번째 글자는 숫자([0123456789]에 속한 숫자)와 일치합니다. sam.xls에서 m은 열 개의 숫자 중 무엇과도 일치하지 않습니다.
정규표현식을 사용할 때, 이처럼 0부터 9, A부터 Z 같이 문자들의 범위를 지정하는 일이 자주 있습니다. 문자 범위를 단순하게 만들 때 정규표현식에서는 특별한 메타 문자인 하이픈(-)을 제공합니다.
아래 정규표현식은 바로 위에서 봤던 것과 동일하지만, 패턴에 범위를 지정해주었습니다.
'[ns]a[0-9]\.xls'
'[0-9]' 패턴은 '[0123456789]'와 같습니다. 따라서 결과도 앞서 본 결과와 동일합니다.
범위를 단지 숫자에만 사용할 수 있는 것은 아닙니다. 다음과 같은 범위에도 모두 사용할 수 있습니다.
- A-Z : A부터 Z까지에 있는 모든 대문자와 일치
- a-z : a부터 z까지에 있는 모든 소문자와 일치
- A-F : A부터 F까지에 있는 대문자와 일치
- A-z : 아스키(ASCII) 문자 A와 아스키 문자 z 사이에 있는 모든 문자와 일치. 이 패턴은 사용하지 않는 것을 추천하는데, 이 사이에 있는 아스키 문자 중에는 여는 대괄호([)와 '^'와 같은 문자도 포함되기 때문입니다.
아스키 문자 가운데 아무거나 두 개를 선택해 한 범위의 시작과 마지막을 표시할 수 있지만, 실제 사용할 때는 숫자 전체를 범위로 정하기고 하고, 일부만 정하기도 합니다. 마찬가지로 영문자도 일부만 범위로 지정하기도 하고 전체를 지정하기도 합니다.
범위를 지정할 때는 두 값 중 더 큰 값이 앞에 나오면 안됩니다. 예를 들어, '[3-1]'과 같은 패턴은 동작하지 않습니다.
하이픈(-)은 대괄호([]) 안에서만 메타 문자인 특수한 메타 문자입니다. 집합 밖에서 하이픈은 단순히 문자 그대로 '-'과 일치합니다. 따라서 집합 밖에서 하이픈 문자에 굳이 역슬래시를 붙일 필요가 없습니다.
범위 여러 개를 집합 하나에 합칠 수도 있습니다. 예를 들어, '[A-Za-z0-9]' 패턴은 대소문자를 포함해서 모든 영문자, 숫자와 일치하며 숫자와 문자가 아닌 경우는 일치하지 않습니다. 이 패턴은 펼치면 다음과 같습니다.
'[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]'
이처럼 범위를 지정하면 정규표현식이 더욱 깔끔해집니다.
추가로 RGB값을 찾는 예제를 살펴보도록 하겠습니다. 웹페이지에서 RGB값은 #000000(검정), #FFFFFF(하양), #FF0000(빨강) 등으로 나타냅니다. RGB값은 대문자와 소문자를 가리지 않습니다. 따라서 #FF00ff(자홍)도 올바른 표기입니다.
body {
background-color: #fefbd8;
}
h1 {
background-color: #0000ff;
}
div {
background-color: #d0f4e6;
}
span {
background-color: #f08970;
}
위 예문에서 RGB값을 찾으려면 다음의 정규표현식을 사용하면 됩니다.
'#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'
여기서 사용한 패턴에서 '#' 문자가 문자 그대로 일치하고, '[0-9A-Fa-f]' 문자 집합이 여섯 번 반복됩니다. 이 패턴은 # 문자와 그 뒤로 이어지는 문자 집합 여섯 개가 예문과 일치하는데, 이 문자들은 숫자나 A와 F 사이의 문자이며, 대소문자는 구별하지 않습니다.
'제외하고' 찾기
문자 집합은 일반적으로 찾고 싶은 문자의 목록을 정하는 데 사용하지만, 찾을 때 제외하고 싶은 문자 목록을 지정할 때도 사용할 수 있습니다. 즉, '여기서 지정한 목록을 제외하고 찾는다'라고 할 수 있습니다.
몇 개만 빼고 대부분의 문자를 포함해야 할 경우에는 패턴이 너무 길어지므로 원하는 문자를 모두 나열하기보다는 '^' 문자를 사용해서 제외할 문자 집합을 지정합니다. 다음 예문을 살펴보겠습니다.
sales1.xls
orders3.xls
sales2.xls
sales3.xls
apac1.xls
europe2.xls
sam.xls
na1.xls
na2.xls
sa1.xls
ca1.xls
여기서 '[ns]a[^0-9]\.xls' 패턴을 사용한 결과는 다음과 같습니다.
이번 예제에서는 앞에서 살펴봤던 것과 정반대 패턴을 사용했습니다. '[0-9]'는 모든 숫자와 일치합니다. 하지만 '[^0-9]'는 정해진 범위 내에 있는 숫자와 일치하지 않습니다. 즉, '[ns]a[^0-9]\.xls'는 na1.xls, na2.xls, sa1.xls와는 일치하지 않고, sam.xls와 일치합니다.
여기서 '^' 문자는 이 문자 바로 뒤에 있는 문자나 범위뿐만 아니라 집합 안에 있는 문자나 범위를 모두 제외합니다.
'프로그래밍 > 정규표현식' 카테고리의 다른 글
[REGEX] 하위 표현식 (Subexpression) (0) | 2022.04.08 |
---|---|
[REGEX] 위치 찾기 (Position Matching) (0) | 2022.04.07 |
[REGEX] 반복 찾기 (0) | 2022.04.06 |
[REGEX] 메타 문자 (0) | 2022.04.05 |
[REGEX] 문자 하나 찾기 (0) | 2022.04.03 |
댓글