데이터 검색 및 분류 솔루션은 민감한 데이터를 식별하기 위해 정규 표현식(때로는 RegExes, REs 또는 RegEx 패턴이라고도 함)에 크게 의존합니다. 하지만 RegExes란 무엇이며, 민감한 데이터를 발견하는 데 어떻게 활용할 수 있을까요? 함께 알아봅시다.
정규 표현식(Regular expressions)은 규모는 작지만 매우 특화된 프로그래밍 언어이며, 기본적으로 ‘와일드카드에 더 강력한 성능을 더한 것’에 가깝습니다. 이 작은 언어를 사용하면, 원하는 문자열을 어떤 규칙으로 찾을지 정의할 수 있습니다. 예를 들어, 이메일 주소, PII, PHI 또는 신용카드 번호를 찾아내는 RegEx를 정의할 수 있습니다.
정규식(Regex) 구성 요소
RegEx에는 리터럴(literals)과 메타문자(metacharacters)를 포함할 수 있습니다.
리터럴
메타문자로 예약된 경우를 제외하면, 어떤 단일 문자든 이미 정규 표현식 자체입니다. 예를 들어, www 는 www.Netwrix.com 과 일치하지만 wwz 는 일치하지 않습니다. 정규 표현식은 대소문자를 구분하므로 www 는 WWW 나 wWw 에는 매치되지 않습니다.
메타문자
다음의 단일 문자는 리터럴로 해석되지 않고 대신 특별한 의미를 갖습니다:
- . ^ $ * + ? { } [ ] | ( )
다음 표는 이러한 각 메타문자가 어떻게 동작하는지 설명합니다.
Type | Meta-characters | Description | Examples |
|---|---|---|---|
|
The dot |
. |
The period means any character. |
net.rix will match both www.netwrix.com and www.netfrix.com. |
|
Character class |
[] |
Matches for anything inside the square brackets. |
You can list characters individually; for instance, net[wrx] will match netw , netr and netx but not netz. |
|
Anchors |
^ |
Used to match characters at the beginning of a string |
^https will match https://netwrix.com but not www.netwrix.com or http://netwrix.com |
|
$ |
Used to match characters at the end of a string |
com$ will match www.netwrix.com or telecom but not computer. |
|
|
Iteration / quantifiers |
? |
Matches the preceding element zero or one time (it will always match if the character was not found). It is great for finding optional characters. |
colou?r will match both color and colour. |
|
|
* |
Matches the preceding element zero or more times instead of zero or once. It is great for finding optional series of characters. |
ne*t will match nt (zero e characters), net (one e ), neeet (three e characters), and so forth. |
|
+ |
Matches the preceding element one or more times. |
ne+t will match net and neeet but not nt. |
|
|
| |
The choice operator matches either the expression before or the expression after the operator. |
net|wrix will match net and wrix. |
|
|
{} |
{x} matches if the element that precedes it is found exactly x times. |
n{3} will match nnn , nnnn and nnnd (because they all include n three times in a row), but it will not match nnw. |
|
|
Blocking and capturing |
() |
Defines a subexpression that can be recalled later using shorthand: The first subexpression in parentheses can be recalled by \1, the second can be recalled by \2 and so on. |
Gr(a|e)y will match Gray or Grey. |
|
Escape sequence |
\ |
The metacharacter that follows the slash will be used as a literal. |
www\.netwrix\.com will match www.netwrix.com but not www,netwrix,com. |
|
Special metacharacters |
\s |
Matches any whitespace character (a space, a tab, a line break or a form feed). |
Netwrix\sAuditor will match Netwrix Auditor, and Netwrix(tab)Auditor, but not Netwrix<5 spaces> Auditor or NetwrixAuditor. |
|
|
\S |
Matches any non-whitespace character. |
\Snetwrix will match Xnetwrix and 1netwrix. |
|
\w |
Matches any alphanumeric character. |
\w\w\w will match net, dfw and Netwrix. |
|
|
\W |
Matches any non-alphanumeric character. |
netwrix\W will match netwrix! and netwrix?. |
|
|
|
\d |
Matches any decimal digit. |
Netwrix\d\d will match Netwrix80 and Netwrix90. |
|
\D |
Matches any non-digit character. |
Netwrix\D will match Netwrix) and Netwrix-. |
|
|
\a |
Matches any single alphabetic character, either capital or lowercase. |
net\arix will match netWrix, netfrix and netarix. |
|
|
|
\b |
Defines a word boundary. |
\brix will match rix and rixon but not netwrix. |
|
|
\B |
Defines a non-word boundary |
\Brix will match Netwrix and trix but not rixon. |
메타문자 조합
이제 거의 모든 메타문자를 알게 되었으니, 이를 조합할 준비가 되었습니다.
예시: 번호판(차량 번호) 번호 찾기
예를 들어 다음 형식의 번호를 찾아야 한다고 가정해 보겠습니다: aaa-nnnn — 처음 세 자리는 영숫자여야 하고, 마지막 네 자리는 숫자여야 합니다. 하이픈(-)은 어떤 문자로든 바뀔 수 있거나 아예 없을 수도 있습니다.
이를 위한 정규식(RegEx)은 다음과 같습니다:
- b[0-9A-Z]{3}([^ 0-9A-Z]|s)?[0-9]{4}b
이 정규식(RegEx)을 자세히 분석해 봅시다:
- b 는 단어 경계를 필요로 하므로, 일치하는 문자열은 더 긴 문자열의 일부가 될 수 없습니다.
- [0-9A-Z]{3} 는 처음 세 문자가 영숫자여야 한다는 뜻입니다.
- ([^ 0-9A-Z]|s)? 는 문자열의 다음 부분이 구분자(영숫자가 아닌 문자 또는 공백 문자)여야 하거나, 아예 아무것도 없어야 한다는 뜻입니다.
- [0-9]{4} 는 문자열의 다음 부분이 4자리 숫자여야 한다는 뜻입니다.
- b 는 다른 단어 경계를 지정합니다.
이 RegEx는 다음 라이선스 번호를 일치시킵니다: NT5-6345, GH3 9452, XS83289
하지만 다음 라이선스 번호에는 일치하지 않습니다: ZNT49371, HG3-29347, nt4-9371
예: 사회보장번호(Social Security number)를 찾는 경우
또 다른 좋은 예는 미국의 사회보장번호(Social Security number, SSN)로, 항상 다음과 같은 형태를 가집니다: nnn-nn-nnnn.
가장 쉬운 정규식(RegEx)은 다음과 같습니다:
- [0-9]{3}-[0-9]{2}-[0-9]{4}
하지만 이 정규식은 오탐(false positive)을 생성합니다. 이 형식을 갖고 있는 모든 숫자가 합법적인 SSN이 아니기 때문입니다. 또한 하이픈 없이 작성된 SSN을 포함해 실제 SSN 중 일부를 놓칠 수도 있습니다. 더 정확한 결과를 얻으려면 더 복잡한 정규식을 만들어야 합니다. 우리는 다음을 알고 있습니다:
- 어떤 숫자 그룹도 전부 0일 수는 없습니다.
- 첫 번째 블록은 666 이거나 900-999일 수 없습니다.
- SSN은 하이픈 대신 공백 문자를 사용해 쓸 수도 있으며, 구분 기호 없이 완전히 붙여서 쓸 수도 있습니다.
- 첫 번째 블록이 7 로 시작한다면, 그 다음에는 0 과 6 사이의 숫자가 와야 하며, 그 뒤에는 어떤 세 번째 자리 숫자도 올 수 있습니다.
따라서 고급 RegEx는 다음과 같이 보일 것입니다:
- b(?!000|666|9d{2})([0-8]d{2}|7([0-6]d))([-]?|s{1})(?!00)dd2(?!0000)d{4}b
이전과 마찬가지로 b 는 시작과 끝에서 단어 경계를 지정합니다. 그 사이에 있는 각 숫자 블록을 더 자세히 살펴봅시다.
첫 번째 블록
- (?!000|666|9d{2}) 는 숫자가 다음으로 시작하면 안 된다고 지정하는 부정적 전방 탐색(negative look-ahead)입니다: 000, 666, 또는 9 뒤에 임의의 두 자리 숫자가 오는 경우.
- ([0-8]d{2} 는 문자열이 다음 범위의 숫자로 시작해야 함을 지정합니다: 0 부터 8 이고 그 뒤에 추가로 두 자리 숫자가 와야 합니다 (0-9) 이어야 합니다.
- |7[0-6]d)) 는 해당 수가 7 로 시작하는 경우, 다음 자리 숫자는 0 와 6 사이여야 하며, 그 뒤에는 임의의 한 자리 숫자가 와야 함을 의미합니다.
- ([-]?|s{1}) 는 세 자리 숫자 뒤에 하이픈, 공백 문자, 또는 첫 번째 블록의 끝을 표시하기 위한 아무것도 없어야 함을 지정합니다.
두 번째 블록
- (?!00) 는 또 다른 부정형 전방 탐색으로, 두 번째 블록에 00 이 없어야 함을 지정합니다.
- dd 는 두 번째 블록에 어떤 두 자리 숫자든 있어야 함을 지정합니다.
- 2 는 두 번째 캡처 그룹과 동일한 텍스트와 일치하며, 이는 ([-]?|s{1}), 따라서 두 번째 블록은 하이픈, 공백 문자 또는 추가 문자 없이 끝날 수 있음을 지정합니다.
세 번째 블록
- (?!0000) 는 또 다른 부정(negative) 전방 탐색(look-ahead)으로, 세 번째 블록에 0이 네 개 올 수 없음을 지정합니다.
- d{4} 은 세 번째 SSN 블록에 임의의 네 자리 숫자가 필요함을 의미합니다.
인기 있는 정규식(RegEx)의 예시
To find | Use this RegEx | Example of match |
|---|---|---|
|
Email addresses |
^[\w\.=-]+@[\w\.-]+\.[\w]{2,3}$ |
T.Simpson@netwrix.com |
|
U.S. Social Security numbers |
\b(?!000|666|9\d{2})([0-8]\d{2}|7([0-6]\d))([-]?|\s{1})(?!00)\d\d\2(?!0000)\d{4}\b |
513-84-7329 |
|
IPV4 addresses |
^\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}$ |
192.168.1.1 |
|
Dates in MM/DD/YYYY format |
^([1][12]|[0]?[1-9])[\/-]([3][01]|[12]\d|[0]?[1-9])[\/-](\d{4}|\d{2})$ |
05/05/2018 |
|
MasterCard numbers |
^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$ |
5258704108753590 |
|
Visa card numbers |
\b([4]\d{3}[\s]\d{4}[\s]\d{4}[\s]\d{4}|[4]\d{3}[-]\d{4}[-]\d{4}[- |
4563-7568-5698-4587 |
|
American Express card numbers |
^3[47][0-9]{13}$ |
34583547858682157 |
|
U.S. ZIP codes |
^((\d{5}-\d{4})|(\d{5})|([A-Z]\d[A-Z]\s\d[A-Z]\d))$ |
97589 |
|
File paths |
\\[^\\]+$ |
\\fs1\shared |
|
URLs |
(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+ |
www.netwrix.com |
유용한 Regex 웹 자료
- https://regexr.com 및 https://regex101.com 은 구문을 강조 표시하고 툴팁을 제공해 여러분의 RegEx를 확인하는 데 도움이 됩니다.
- https://regexcrossword.com 는 단서가 정규식을 사용해 정의되는 크로스워드 퍼즐 게임입니다.
- https://www.regular-expressions.info 정규식에 대한 정보를 제공하는 훌륭한 사이트입니다. 또한 Notepad++ 도구에는 정규식 작업을 하는 동안 유용하게 쓸 수 있는 RegEx 도우미 확장 기능이 있습니다.
공유하기
더 알아보기
저자 소개
Jeff Melnick
시스템 엔지니어링 디렉터
Jeff는 Netwrix의 Global Solutions Engineering 분야 전(前) 디렉터입니다. 그는 오랜 기간 Netwrix 블로거이자 연사, 프레젠터로 활동해 왔습니다. Netwrix 블로그에서 Jeff는 시스템 관리 경험을 크게 향상시킬 수 있는 라이프해킹, 팁, 트릭을 공유합니다.