정규표현식
개요
정규식은 텍스트 문자열에서 패턴을 명시적으로 설명하는 데 사용할 수 있는 언어입니다. 이러한 패턴을 단순히 설명하는 것 외에도 일반적으로 정규식 엔진을 사용하면 일치 항목을 반복하거나 패턴을 구분 기호로 사용하여 문자열을 하위 문자열로 구문 분석하거나 지능적인 방식으로 텍스트를 바꾸거나 형식을 다시 지정할 수 있습니다. 또한 정규식을 사용하여 강력하고 간단한 방식으로 텍스트 처리와 관련된 많은 일반 작업을 해결할 수 있습니다.
단순식
가장 단순한 정규식은 이미 친숙해 있는 정규식인 리터럴 문자열입니다. 특정 문자열을 문자 그대로 설명할 수 있으므로 foo와 같은 정규식 패턴은 입력 문자열 foo와 정확히 한 번 일치합니다. 이러한 경우 이 문자열은 The food was quite taurly 입력과도 일치합니다. 그러나 정확히 일치하는 항목만 찾을 경우 이 입력을 원하지 않을 수 있습니다.
물론 자신과 정확히 일치하는 문자열을 찾는 것은 일반적인 정규식 구현의 결과일 뿐 강력한 기능이라고 말할 수는 없습니다. foo 대신 f로 시작하는 모든 단어를 찾으려는 경우 또는 3자로 된 단어를 찾으려는 경우는 어떨까요? 이 정도 조건이라면 이미 리터럴 문자열로 수행할 수 있는 작업의 범위는 넘어 선 것입니다. 이제 정규식에 대해 더 자세히 배워야 합니다. 다음은 샘플 리터럴 표현식 및 일치하는 일부 입력입니다.
패턴 | 입력(일치항목 |
---|---|
foo | foo, food, foot, "There's evil afoot." |
한정사
한정사를 사용하면 패턴 내에 특정 문자 또는 문자 집합을 반복할 수 있는 횟수를 간단히 지정할 수 있습니다. 다음과 같은 3가지 비명시적 한정사가 있습니다.
*는 "0개 이상의 항목"을 나타냅니다.
+는 "1개 이상의 항목"을 나타냅니다.
?는 "0개 또는 1개의 항목"을 나타냅니다.
한정사는 항상 한정사 바로 앞(왼쪽)에 있는 패턴을 참조합니다. 패턴 그룹을 만드는 데 괄호가 사용되지 않은 경우 이 한정사는 일반적으로 단일 문자입니다. 다음은 몇 가지 샘플 패턴 및 일치하는 입력입니다.
패턴 | 입력(일치항목) |
---|---|
fo* | foo, foe, food, fooot, "forget it", funny, puffy |
fo+ | foo, foe, food, foot, "forget it" |
fo? | foo, foe, food, foot, "forget it", funny, puffy |
주어진 패턴이 정확히 0번 또는 한 번 발생할 수 있도록 지정하는 것 외에도 ‘?’ 문자는 입력 문자열에서 여러 개가 일치할 수 있을 경우 패턴 또는 하위 패턴이 최소 문자 수와 일치하도록 지정합니다.
비명시적 한정사(일반적으로 간단히 한정사라고 하지만 다음 그룹과 구분하기 위함) 외에도 명시적 한정사가 있습니다. 한 가지 패턴으로 발생할 수 있는 횟수와 관련하여 한정사가 모호할 경우 명시적 한정사를 사용하면 정확한 수, 범위 또는 숫자 집합을 지정할 수 있습니다. 정규 한정사와 같이 명시적 한정사는 적용되는 패턴 다음에 위치합니다. 명시적 한정사는 중괄호{} 및 숫자 값을 사용하여 이 괄호 안에 상한 및 하한 발생 수를 지정합니다. 예를 들어 x{5}는 x 문자 5개(xxxxx)와 일치합니다. 숫자 한 개만 지정한 경우 x{5,}와 같이 뒤에 쉼표를 입력하지 않는 한 상한으로 사용됩니다(개수에 상관없이 4개 이상의 x 문자와 일치).
패턴 | 입력(일치항목) |
---|---|
ab{2}c | abbc, aaabbccc |
ab{,2}c | ac, abc, abbc, aabbcc |
ab{2,3}c | abbc, abbbc, aabbcc, aabbbcc |
메타문자
정규식에서 특별한 의미가 있는 구성을 메타 문자라고 합니다. 앞서 *, ?, +, { } 문자 등의 여러 메타 문자에 대해 이미 살펴 보았습니다. 기타 여러 문자는 정규식의 언어로 특별한 의미가 있습니다. 이러한 문자에는 $ ^ . [ ( | ) ] \ 등이 있습니다.
.(마침표 또는 점) 메타 문자는 가장 단순하면서도 가장 많이 사용되는 문자 중 하나입니다. 이 문자는 어떤 단일 문자와도 일치하며, 특정 패턴에 문자 조합이 포함될 수 있지만 한정사를 사용하여 특정 길이 범위 내에 속하도록 지정하는 데 유용합니다. 또한 긴 문자열 내에서 설명하는 패턴의 인스턴스에 식이 일치하는 것도 살펴 보았습니다. 그러나 패턴과 정확히 일치하도록 하려면 어떻게 해야 할까요? 이러한 경우는 우편 번호나 전화 번호에 적합한 형식으로 입력했는지 확인하는 경우와 같이 유효성 검사 시나리오에 자주 일어납니다. ^ 메타 문자는 문자열 또는 줄의 처음을 지정하는 데 사용되며 $ 메타 문자는 문자열이나 줄의 끝을 지정하는 데 사용됩니다. 이러한 문자를 패턴의 처음과 끝에 추가하면 패턴에 정확히 일치하는 입력 문자열에만 일치하도록 할 수 있습니다. 또한 ^ 메타 문자는 대괄호 [ ]로 지정되는 문자 클래스의 처음에 사용될 경우 특별한 의미가 있습니다. 이 내용은 아래에서 설명하겠습니다.
\(백슬래시) 메타 문자는 문자가 특별한 의미를 가지지 않도록 하는 데 사용되며 미리 정의된 메타 문자 집합의 인스턴스를 지정하는 데 사용됩니다. 이 내용도 아래에서 설명하겠습니다. 정규식이 메타 문자의 리터럴 버전을 포함하도록 하려면 백슬래시를 사용하여 특정 의미를 해제해야 합니다. 그러므로 인스턴스에 대해 "c:\"로 시작하는 문자열과 일치시키려는 경우 ^c:\\를 사용할 수 있습니다. 여기서 ^ 메타 문자를 사용하여 문자열이 이 패턴으로 시작되도록 지정했으며 백슬래시 메타 문자를 사용하여 리터럴 백슬래시를 해제했다는 점에 유의하십시오.
|(파이프) 메타 문자는 교체에 사용되며 기본적으로 패턴에서 'A 또는 B'를 지정합니다. 그러므로 a|b와 같은 입력은 'a' 또는 'b'가 포함된 어떤 내용에도 일치하며 문자 클래스 [ab]와 매우 비슷합니다.
마지막으로, 괄호 ( )는 패턴을 그룹화하는 데 사용됩니다. 가독성만을 위해 한정사를 사용하여 전체 패턴이 여러 번 발생하도록 허용하거나 입력의 특정 부분이 개별적으로 일치하도록 하여 서식을 다시 지정하거나 구문 분석을 수행하기 위해 패턴을 그룹화할 수 있습니다.
다음은 메타 문자 사용의 예를 보여 줍니다.
패턴 | 입력(일치항목) |
---|---|
. | a, b, c, 1, 2, 3 |
.* | Abc, 123, 모든 문자열, 심지어 문자가 없어도 일치 |
^c:\\ | c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자 |
abc$ | abc, 123abc, abc로 끝나는 모든 문자열 |
(abc){2,3} | abcabc, abcabcabc |
문자 클래스
문자 클래스는 대괄호 [ ]로 둘러 쌓여 정의되는 것으로, 정규식 내의 소언어입니다. 가장 단순한 문자 클래스는 [aeiou]와 같이 단순히 괄호 안에 있는 문자 목록입니다. 식 안에 사용할 경우 이러한 문자 중 하나를 패턴 내의 이 위치에 사용할 수 있습니다. 그러나 한정사를 사용하지 않을 경우에 한하여 한 번만 사용할 수 있습니다. 문자 클래스를 사용할 경우 단어나 패턴은 정의할 수 없으며 단일 문자만 정의할 수 있습니다.
숫자를 지정하려면 문자 클래스 [0123456789]를 사용할 수 있습니다. 그러나 이렇게 길게 쓰면 오히려 사용하기 불편할 수 있으므로 하이픈 문자(-)를 사용하여 괄호 안에 문자 범위를 정의할 수 있습니다. 이 하이픈 문자는 문자 클래스에서만 특별한 의미가 있을 뿐 정규식에서는 별다른 의미가 없으므로 정규식 메타 문자로 정확히 한정하지는 않습니다. 또한 문자 클래스에서도 첫 문자가 아닌 경우에만 특별한 의미가 있습니다. 하이픈을 사용하여 숫자를 지정하려면 [0-9]를 사용합니다. 마찬가지로 소문자의 경우 [a-z]를 사용하고 대문자의 경우 [A-Z]를 사용하면 됩니다. 하이픈으로 정의되는 범위는 사용 중인 문자 집합에 따라 다르므로 ASCII 또는 유니코드 테이블 등에서의 문자 순서는 해당 범위에 포함되는 문자를 결정합니다. 범위에 하이픈을 포함해야 할 경우에는 첫 문자로 지정합니다. 예를 들어 [-.? ]는 이 4개 문자 중 하나와 일치합니다(마지막 문자는 공백). 또한 정규식 메타 문자는 문자 클래스 내에서 특별하게 처리되지 않으므로 의미를 해제할 필요가 없습니다. 문자 클래스는 고유 규칙과 구문을 사용하므로 나머지 정규식과는 다른 별도의 언어로 간주해야 합니다.
또한 문자 클래스에서 캐럿(^)을 첫 문자로 사용하여 문자 클래스를 빼면 문자 클래스의 구성원을 제외하고 임의의 문자를 일치시킬 수 있습니다. 그러므로 모음이 아닌 문자를 일치시키려면 [^aAeEiIoOuU]와 같은 문자 클래스를 사용할 수 있습니다. 하이픈을 빼려는 경우 -과 같이 문자 클래스에서 두 번째 문자로 입력해야 합니다. 문자 클래스에서 ^ 문자는 정규식 패턴의 첫 문자로 사용할 때와 전혀 다른 의미를 가진다는 점에 유의하십시오.
다음은 사용 중인 문자 클래스의 예를 보여 줍니다.
패턴 | 입력(일치항목) |
---|---|
^b[aeiou]t$ | Bat, bet, bit, bot, but |
^[0-9]{5}$ | 11111, 12345, 99999 |
^c:\\ | c:\windows, c:\\\\\, c:\foo.txt, c:\ 다음에 오는 임의의 문자 |
abc$ | abc, 123abc, abc로 끝나는 모든 문자열 |
(abc){2,3} | abcabc, abcabcabc |
^[^-][0-9]$ | 0, 1, 2, … (-0, -1, -2 등과 일치하지 않음) |
미리 정의된 메타 문자 집합
지금까지 설명한 도구를 사용하여 수많은 작업을 수행할 수 있습니다. 그러나 패턴에서 모든 숫자에 대해 [0-9]라고 사용하는 것도 길다고 볼 수 있으며 영숫자 문자에서 [0-9a-zA-Z]와 같이 사용할 경우에는 더 불편합니다. 이와 같이 일반적이지만 매우 긴 패턴의 불편함을 없애기 위해 메타 문자 집합을 미리 정의했습니다. 정규식을 다르게 구현하면 미리 정의된 메타 문자 집합도 다르게 정의됩니다. 여기서 설명하는 메타 문자 집합은 .NET Framework의 System.Text.Regular- Expressions API에서 지원됩니다. 미리 정의된 이러한 메타 문자의 표준 구문은 백슬래시(\) 다음에 하나 이상의 문자를 입력하는 것입니다. 대부분의 미리 정의된 메타 문자 길이는 문자 하나이므로 쉽게 사용할 수 있고 긴 문자 클래스 대신에 편리하게 사용할 수 있습니다. 두 가지 예로, 임의의 숫자와 일치하는 \d와 단어 문자(영숫자와 밑줄)와 일치하는 \w가 있습니다. 유니코드 캐리지 리턴 문자와 일치하는 \u000D와 같이, 일치하는 문자의 주소를 지정해야 하는 특수 문자 코드 일치는 예외입니다. 가장 일반적으로 사용하는 문자 클래스와 해당 메타 문자는 다음과 같습니다.
메타 문자 | 해당 문자 클래스 |
---|---|
\a | 벨(경보)과 일치합니다. \u0007 |
\b | 문자 클래스 안에 사용되는 경우를 제외하고 단어 경계와 일치합니다. 백슬래시 문자 \u0008과 일치합니다. |
\t | 탭과 일치합니다. \u0009 |
\r | 캐리지 리턴과 일치합니다. \u000D |
\w | 세로 탭과 일치합니다. \u000B |
\f | 용지 공급과 일치합니다. \u000C |
\n | 새 행과 일치합니다. \u000A |
\e | 이스케이프와 일치합니다. \u001B |
\040 | 세 자리 8진수를 사용하는 ASCII 문자와 일치합니다. \040은 공백을 나타냅니다(십진수 32). |
\x20 | 두 자리 16진수를 사용하는 ASCII 문자와 일치합니다. 이 경우 \x2-는 공백을 나타냅니다. |
\cC | ASCII 컨트롤 문자와 일치합니다. 이 경우 ctrl-C입니다. |
\u0020 | 정확히 4자리 16진수를 사용하는 유니코드 문자와 일치합니다. 이 경우 \u0020은 공백입니다. |
\* | 미리 정의된 문자 클래스를 나타내지 않는 문자는 단순히 해당 문자로 처리됩니다. 그러므로 \*는 \x2A와 같습니다(*는 메타 문자가 아니라 리터럴임). |
\p{name} | 명명된 문자 클래스 'name'에 있는 임의의 문자와 일치합니다. 지원되는 이름은 유니코드 그룹 및 블록 범위입니다. 예를 들어 Ll, Nd, Z, IsGreek, IsBoxDrawing 및 Sc(통화)와 같습니다. |
\P{name} | 명명된 문자 클래스 'name'에 포함되지 않은 텍스트와 일치합니다. |
\w | 임의의 단어 문자와 일치합니다. 비유니코드 및 ECMAScript 구현의 경우 [a-zA-Z_0-9]와 같습니다. 유니코드 범주에서는 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다. |
\W | \w를 빼고, ECMAScript 규격 집합 [^a-zA-Z_0-9] 또는 유니코드 문자 범주 [^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]와 같습니다. |
\s | 공백 문자와 일치합니다. 유니코드 문자 클래스 [\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \s는 \f\n\r\t\v와 같습니다. |
\S | 공백이 아닌 문자와 일치합니다. 유니코드 문자 범주 [^\f\n\r\t\v\x85\p{Z}]와 같습니다. ECMAScript 옵션을 사용하여 ECMAScript 규격 동작을 지정한 경우 \S는 [^ \f\n\r\t\v](^ 다음에 공백이 있음)와 같습니다. |
\d | 십진수와 일치합니다. 유니코드의 경우 [\p{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [0-9]와 같습니다. |
\D | 십진수가 아닌 숫자와 일치합니다. 유니코드의 경우 [\P{Nd}]와 같고, 비유니코드 ECMAScript 동작의 경우 [^0-9]와 같습니다. |
샘플 식
대부분의 경우 예를 들어 설명할 때 가장 효과적으로 이해할 수 있으므로 여기서 몇 가지 샘플 식을 보여 드리겠습니다.
메타 문자 | 해당 문자 클래스 |
---|---|
^\d{5}$ | 미국 우편 번호와 같은 5자리 숫자입니다. |
^(\d{5})|(\d{5}-\d{4}$ | 5자리 숫자 또는 5자리 숫자-대시-4자리 숫자입니다. 미국 우편 번호 또는 미국 우편 번호+4 형식과 일치합니다. |
^(\d{5}(-\d{4})?$ | 앞의 예와 같지만 더 효율적입니다. ?를 사용하면 교체를 통해 별도의 패턴 두 개를 개별적으로 비교해야 하는 대신에 패턴의 4자리 부분을 선택적으로 입력할 수 있습니다. |
^[+-]?\d+(\.\d+)?$ | 실수와 일치하며 선택적으로 기호를 사용할 수 있습니다. |
^[+-]?\d*\.?\d*$ | 위의 예와 같지만 빈 문자열에도 일치합니다. |
^(20|21|22|23|[01]\d)[0-5]\d$ | 24시간 값과 일치합니다. |
/\*.*\*/ | C 스타일 주석 /* … */의 내용과 일치합니다. |
예제) CC Attack 패턴그룹 추가
헤드필드 값에 대한 보안 설정으로 CC Attack(cache control) 방지하기
- 상위 탭에서 템플릿관리에서 보안 패턴 클릭
- 사용자 탭->그룹추가->그룹추가에 하위 [참조 그림 1] 과 같이 입력
- [정책관리]->(CC Attack을 방지하고자 하는 도메인 그룹 선택)->팝업 메뉴에 [정책설정]
- [헤드필드값정책]->[Cache-Control]->[정책입력]
- 보안정책 입력->CCAtack 대응 방법과 로그종류 설정 후 [확인]