정규 표현식이란 정확히 무엇인가요?
문자는 컴퓨터 소프트웨어가 텍스트를 처리할 때 가장 기본적인 단위로 문자, 숫자, 구두점, 공백, 줄바꿈, 한자 등이 될 수 있습니다. 문자열은 0개 이상의 문자로 구성된 시퀀스입니다. 텍스트는 텍스트, 문자열입니다. 특정 문자열이 특정 정규 표현식과 일치한다는 것은 일반적으로 문자열의 일부(또는 여러 부분)가 표현식에서 제공하는 조건을 충족할 수 있음을 의미합니다.
문자열을 처리하는 프로그램이나 웹페이지를 작성할 때 특정 복잡한 규칙과 일치하는 문자열을 찾아야 하는 경우가 종종 있습니다. 정규식은 이러한 규칙을 설명하는 데 사용되는 도구입니다. 즉, 정규식은 텍스트 규칙을 기록하는 코드입니다.
Windows/Dos에서 파일 검색에 와일드카드, 즉 * 및 ?를 사용했을 가능성이 높습니다. 특정 디렉터리에 있는 모든 Word 문서를 찾으려면 *.doc를 검색하면 됩니다. 여기서 *는 임의의 문자열로 해석됩니다. 와일드카드와 유사하게 정규식도 텍스트 일치에 사용되는 도구이지만 와일드카드보다 요구 사항을 더 정확하게 설명할 수 있습니다. 물론 더 복잡해지는 대가를 치르게 됩니다. 예를 들어 정규식을 작성하여 모든 항목을 찾는 데 사용됩니다. 0으로 시작하는 문자열, 2~3자리 숫자, 하이픈 "-", 마지막으로 7~8자리 숫자(예: 010-12345678 또는 0376-7654321).
시작하기
정규식을 배우는 가장 좋은 방법은 예제로 시작한 다음, 이해한 후 예제를 수정하고 실험해 보는 것입니다. 그들을. 아래에는 여러 가지 간단한 예가 나와 있으며 자세히 설명되어 있습니다.
영어 소설에서 hi를 검색한다고 가정하면 정규 표현식 hi를 사용할 수 있습니다.
이것은 거의 가장 간단한 정규식입니다. 다음과 같이 문자열을 정확하게 일치시킬 수 있습니다. 두 문자로 구성되며 첫 번째 문자는 h이고 마지막 문자는 i입니다. 일반적으로 정규식을 처리하는 도구는 대소문자를 무시하는 옵션을 제공합니다. 이 옵션을 선택하면 hi, HI, Hi 및 hI의 네 가지 대소문자 중 하나와 일치할 수 있습니다.
안타깝게도 Him, History, High 등 Hi라는 두 글자가 연속으로 포함된 단어가 많습니다. hi를 사용하여 검색하면 안에 있는 hi도 검색됩니다. hi라는 단어를 정확하게 찾으려면 bhib를 사용해야 합니다.
b는 정규식(뭐, 메타문자라고 부르는 사람도 있음)으로 지정되는 특수 코드로, 단어의 시작이나 끝, 즉 단어의 경계를 나타냅니다. 영어 단어는 일반적으로 공백, 구두점 또는 줄 바꿈으로 구분되지만 b는 이러한 단어 구분 문자와 일치하지 않고 한 위치에만 일치합니다.
더 정확하게 말하면 b는 앞뒤의 문자가 둘 다가 아닌(one is, one is not or does not) w인 위치와 일치합니다.
찾고 있는 사람이 안녕 뒤에 루시가 근처에 있다면 bhib.*bLucyb를 사용하세요.
여기서 .는 개행 문자를 제외한 모든 문자와 일치하는 또 다른 메타 문자입니다. *도 메타 문자이지만 문자나 위치가 아니라 수량을 나타냅니다. * 앞의 내용을 여러 번 반복하여 전체 표현식을 일치시킬 수 있음을 지정합니다. 따라서 .*는 함께 개행 문자를 포함하지 않는 문자 수를 의미합니다. 이제 bhib.*bLucyb의 의미는 분명합니다. 먼저 hi라는 단어, 그 다음에는 원하는 수의 문자(개행은 제외), 마지막으로 Lucy라는 단어입니다.
개행 문자는 'n'이고, ASCII 코드는 10(16진수 0x0A) 문자입니다.
다른 메타 문자를 함께 사용하면 더욱 강력한 정규식을 구성할 수 있습니다. 예를 들어, 다음 예:
0dd-dddddddd는 0으로 시작하고 두 자리, 하이픈 "-", 마지막으로 8자리(즉, 중국 전화번호 Number.)로 구성된 문자열과 일치합니다. , 이 예는 지역번호가 3자리인 상황에만 일치할 수 있습니다.
여기서 d는 한 자리 숫자(0, 1, 2, 또는...)와 일치하는 새로운 메타 문자입니다. - 은(는) 메타 문자가 아니며 하이픈(또는 빼기 기호, 하이픈 또는 원하는 이름) 자체와만 일치합니다.
너무 많은 귀찮은 반복을 피하기 위해 이 표현식을 다음과 같이 쓸 수도 있습니다: 0d{2}-d{8}. 여기서 d 뒤의 {2}({8})는 이전 d를 2번(8번) 반복하고 일치해야 함을 의미합니다.
정규식 테스트
기타 사용 가능한 테스트 도구:
RegexBuddy
Javascript 정규식 온라인 테스트 도구
정규식을 읽고 쓰는 것이 어렵지 않다면 당신은 천재이거나 지구인이 아닙니다. 정규식의 구문은 정기적으로 사용하는 사람에게도 혼란스러울 수 있습니다. 읽고 쓰기가 어렵고 오류가 발생하기 쉽기 때문에 정규식을 테스트할 수 있는 도구를 찾는 것이 필요합니다.
정규식의 일부 세부 사항은 환경에 따라 다릅니다. 이 튜토리얼에서는 Microsoft .Net Framework 2.0에서 정규식의 동작을 소개하므로 .Net Regex Tester의 도구를 소개하겠습니다. 먼저 .Net Framework 2.0이 설치되어 있는지 확인한 다음 Regex Tester를 다운로드하세요. 이것은 친환경 소프트웨어입니다. 다운로드한 후 압축된 패키지를 열고 RegexTester.exe를 직접 실행하세요.
다음은 Regex Tester 실행 스크린샷입니다.
메타 문자
이제 b,.,*, d와 같은 몇 가지 유용한 메타 문자를 이미 알고 계셨습니다. 공백, 탭, 줄 바꿈, 중국어 전각 문자를 포함하여 모든 공백 문자와 일치하는 s와 같은 정규 표현식에는 더 많은 메타 문자가 있습니다. 공간 등 w는 문자, 숫자, 밑줄, 한자 등과 일치합니다.
한자/한자의 특수 처리는 .Net에서 제공하는 정규식 엔진을 통해 지원됩니다. 기타 환경에서의 자세한 내용은 관련 문서를 확인하세요.
다음은 몇 가지 예입니다.
baw*b는 문자 a로 시작하는 단어와 일치합니다. 먼저 단어의 시작 부분(b), 그 다음 문자 a, 그 다음 임의 개수의 문자 또는 숫자(w*), 단어 끝(b)이 옵니다.
좋아, 이제 정규 표현식의 단어가 의미하는 바에 대해 이야기해 보겠습니다. 최소 하나의 연속 w. 네, 이것은 영어를 배울 때 외워야 하는 같은 이름을 가진 수천 가지의 것들과는 전혀 관련이 없습니다 :)
d+는 1개 이상의 연속된 숫자와 일치합니다. 여기서 +는 *와 유사한 메타 문자입니다. 차이점은 *는 여러 번(아마도 0회) 반복되는 것과 일치하는 반면, +는 1회 이상 반복되는 것과 일치한다는 것입니다.
bw{6}b는 정확히 6자로 구성된 단어와 일치합니다.
표 1. 일반적으로 사용되는 메타 문자
정규식 엔진은 일반적으로 "지정된 문자열이 정규식과 일치하는지 테스트"하는 방법을 제공합니다. RegExp와 같은 메서드 JavaScript의 .test() 메서드 또는 .NET의 Regex.IsMatch() 메서드. 여기서 일치한다는 것은 문자열 중 표현 규칙을 따르는 부분이 있는지 여부를 나타냅니다. d{5,12}에 대해 ^ 및 $를 사용하지 않는 경우 이 방법을 사용하면 전체 문자열이 5~12자리가 아닌 문자열에 5~12개의 연속 숫자만 포함되도록 할 수 있습니다.
메타 문자 ^(숫자 6과 동일한 키의 기호) 및 $는 모두 b와 다소 유사한 위치와 일치합니다. ^는 찾고 있는 문자열의 시작 부분과 일치하고 $는 끝 부분과 일치합니다. 이 두 코드는 입력 내용을 확인할 때 매우 유용합니다. 예를 들어 웹 사이트에서 QQ 번호를 5~12자리로 입력해야 하는 경우 ^d{5,12}$를 사용할 수 있습니다.
여기서 {5,12}는 이전에 소개된 {2}와 유사합니다. 단, {2} 일치는 더도 덜도 없이 두 번만 반복될 수 있으며 {5,12}가 반복됩니다. 횟수는 5회 미만일 수 없으며 12회를 초과할 수 없으며, 그렇지 않으면 일치하지 않습니다.
^, $를 사용하기 때문에 전체 입력 문자열을 사용하여 d{5,12}와 일치해야 하는데, 이는 전체 입력이 5~12개의 숫자여야 한다는 의미이므로 입력이 QQ 숫자인 경우 이 정규식과 일치할 수 있으면 요구 사항을 충족합니다.
대소문자 무시 옵션과 유사하게 일부 정규식 처리 도구에는 여러 줄을 처리하는 옵션도 있습니다. 이 옵션을 선택하면 ^와 $의 의미가 일치하는 줄의 시작과 끝이 됩니다.
문자 탈출
., * 등의 메타 문자 자체를 검색하려는 경우 문제가 있습니다. 메타 문자는 다른 것으로 해석되기 때문에 지정할 수 없습니다. 이때 해당 문자의 특별한 의미를 취소하기 위해 사용해야 합니다. 따라서 . 및 *를 사용해야 합니다. 물론 자체적으로 검색하려면 \.
도 사용해야 합니다. 예를 들어 deerchao.net은 deerchao.net과 일치하고 C:\Windows는 C:Windows와 일치합니다.
반복
이미 *, +, {2}, {5,12} 방식의 이전 일치 반복을 보셨습니다. 다음은 정규식의 모든 한정자입니다(*, {5,12} 등의 지정된 코드 수).
표 2. 일반적으로 사용되는 한정자
다음은 반복 사용의 몇 가지 예입니다.
Windowsd+는 Windows 뒤에 하나 이상의 숫자가 오는 것과 일치합니다.
^w+는 줄의 첫 번째 단어(또는 전체 문자열과 일치합니다. 의 단어, 구체적인 일치 의미는 옵션 설정에 따라 다름)
문자 클래스
숫자, 문자 또는 숫자를 찾으려면 공백이 매우 중요합니다. 간단합니다. 이러한 문자 집합에 해당하는 메타 문자가 이미 있기 때문입니다. 하지만 미리 정의된 메타 문자(예: 모음 a, e, i, o, u)가 없는 문자 집합을 일치시키려면 어떻게 해야 할까요?
아주 간단합니다. [aeiou]는 모든 영어 모음과 일치하고, [.?!]는 구두점(. 또는? 또는!)과 일치합니다.
문자 범위를 쉽게 지정할 수도 있습니다. 예를 들어 [0-9]는 d와 정확히 동일한 의미를 나타내며 마찬가지로 [a-z0-9A-Z_]도 완전히 동일합니다. . w (영어만 고려하는 경우).
다음은 좀 더 복잡한 표현입니다: (?0d{2}[) -]?d{8}.
"(" 및 ")"도 메타 문자이므로 나중에 그룹화 섹션에서 언급할 것이므로 여기서 이스케이프해야 합니다.
이 표현식은 (010)88886666, 022-22334455, 02912345678 등 다양한 형식의 전화번호와 일치할 수 있습니다. 이에 대한 몇 가지 분석을 해보겠습니다. 먼저 이스케이프 문자가 있습니다(0 또는 1번 나타날 수 있음(?), 그 다음 0, 그 뒤에 2자리 숫자(d{2})가 올 수 있음) 또는 - 또는 공백 중 하나 , 1번 나오든 안 나오든(?) 마지막으로 8자리 숫자(d{8})가 나타납니다.
분기 조건
안타깝게도 방금 표현은 010)12345678 또는 (022-87654321 "Corright"처럼 "No"와도 일치할 수 있습니다. 이 문제를 해결하려면 분기 조건을 사용해야 합니다. 정규식의 분기 조건은 이러한 규칙 중 하나라도 충족되면 구분을 사용하는 것입니다. 이해가 안 되시나요? 문제가 되지 않습니다. 예를 살펴보세요.
0d{2}-d{8}|0d{3}-d{7}는 두 가지 유형과 일치할 수 있습니다. 하이픈으로 구분된 숫자: 하나는 3자리 지역 번호와 8자리 지역 번호(예: 010-12345678)이고, 다른 하나는 4자리 지역 번호와 7자리 지역 번호(0376-2233445)입니다.
(0d{2})[- ]?d{8}|0d{2}[- ]?d{8} 이 표현식은 3자리 지역 번호가 있는 전화번호와 일치합니다. 여기서 지역 번호는 다음과 같습니다. 지역번호와 지역번호는 하이픈이나 공백으로 구분하거나 구분하지 않아도 됩니다. 분기 조건을 사용하여 이 표현식을 확장하여 4자리 지역 코드도 지원할 수 있습니다.
d{5}-d{4}|d{5} 이 표현식은 미국의 우편번호를 일치시키는 데 사용됩니다. 미국 우편번호 규칙은 5자리 또는 하이픈으로 구분된 9자리입니다. 이 예제를 제공하는 이유는 문제를 설명할 수 있기 때문입니다. 분기 조건을 사용할 때 각 조건의 순서에 주의하세요. d{5}|d{5}-d{4}로 변경하면 5자리 우편번호(및 9자리 우편번호 중 처음 5자리)만 일치합니다. 그 이유는 분기 조건을 일치시킬 때 각 조건이 왼쪽에서 오른쪽으로 테스트되기 때문입니다. 특정 분기가 만족되면 다른 조건은 고려되지 않습니다.
그룹화
이미 단일 문자를 반복하는 방법을 언급했습니다(문자 바로 뒤에 한정자를 추가하면 됩니다). 여러 문자가 반복되면 어떻게 해야 하나요? 괄호를 사용하여 하위 표현식(그룹화라고도 함)을 지정한 다음 이 하위 표현식의 반복 횟수를 지정할 수도 있습니다(나중에 소개됨).
(d{1,3}.){3}d{1,3}는 간단한 IP 주소 일치 표현식입니다. 이 표현식을 이해하려면 다음 순서로 분석하세요. d{1,3}은 1~3자리 숫자와 일치하고, (d{1,3}.){3}은 세 자리 숫자에 마침표를 더한 것과 일치합니다(이것은 전체가 이 그룹)을 세 번 반복하고 마지막으로 1~3자리 숫자(d{1,3})가 추가됩니다.
IP 주소의 숫자는 255보다 클 수 없습니다. "24" 시즌 3의 작가들이 속지 않도록 하세요...
안타깝게도 일치합니다. 256.300 .888.999와 같은 IP 주소는 존재할 수 없습니다. 산술 비교를 사용할 수 있으면 이 문제를 간단하게 해결할 수 있지만 정규식은 수학 함수를 제공하지 않으므로 긴 그룹화, 선택 및 문자 클래스만 사용하여 올바른 IP 주소를 설명할 수 있습니다.( (2 [0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?).
이 표현을 이해하는 열쇠는 2[0-4]d|25[0-5]|[01]?dd?를 이해하는 것입니다. 여기서는 자세히 설명하지 않겠습니다. 스스로 분석해서 그 의미를 알아보세요.
반의어
쉽게 정의된 문자 클래스에 속하지 않는 문자를 찾아야 하는 경우가 있습니다. 예를 들어 숫자 이외의 문자를 찾으려면 반의어를 사용해야 합니다.
표 3. 일반적으로 사용되는 반의어 코드
역참조
괄호를 사용하여 하위 표현식을 지정한 후 이 하위 표현식과 일치하는 텍스트(즉, 이 그룹에서 캡처한 콘텐츠)를 표현식이나 다른 프로그램에서 추가로 처리할 수 있습니다. 기본적으로 각 그룹에는 자동으로 그룹 번호가 있습니다. 규칙은 다음과 같습니다. 왼쪽에서 오른쪽으로, 그룹의 왼쪽 괄호를 표시로 사용하여 첫 번째 나타나는 그룹의 그룹 번호는 1, 두 번째 나타나는 그룹의 그룹 번호는 2입니다. 등등.
어... 사실 그룹 번호 할당은 방금 말한 것처럼 간단하지 않습니다.
그룹 0은 전체 정규식에 해당합니다.
사실 그룹 번호는 할당 프로세스는 왼쪽에서 오른쪽으로 두 번 스캔해야 합니다. 첫 번째 패스는 이름이 없는 그룹에만 할당되고, 두 번째 패스는 이름이 지정된 그룹에만 할당됩니다. 따라서 모든 이름이 지정된 그룹의 그룹 번호는 이름이 없는 그룹 번호보다 큽니다.
(?:exp) 등의 구문을 사용하여 그룹 번호 할당에 참여할 수 있는 권한을 그룹에서 박탈할 수 있습니다.
역참조는 이전 그룹과 일치하는 텍스트를 반복적으로 검색하는 데 사용됩니다. 예를 들어 1은 그룹 1과 일치하는 텍스트를 나타냅니다. 이해하기 어렵나요? 예를 참조하세요.
b(w+)bs+1b는 go go 또는 kitty kitty와 같이 반복되는 단어를 찾는 데 사용할 수 있습니다. 이 표현은 먼저 단어, 즉 단어의 시작과 끝 사이에 두 개 이상의 문자나 숫자(b(w+)b)가 포함됩니다. 이 단어는 1번 그룹에 캡처되고 그 다음에는 1개 이상의 공백이 캡처됩니다. 문자(s+), 마지막으로 그룹 1에 캡처된 콘텐츠(즉, 이전에 일치하는 단어)(1)입니다.
하위 표현식의 그룹 이름을 직접 지정할 수도 있습니다. 하위 표현식의 그룹 이름을 지정하려면 다음 구문을 사용하십시오: (?<Word>w+)(또는 꺾쇠 괄호를 ': (?'Word'w+)로 대체). 그러면 그룹 이름은 w+입니다. 이름은 다음과 같습니다. 워드로 지정되었습니다. 이 그룹에서 캡처한 콘텐츠를 역참조하려면 k<Word>를 사용할 수 있으므로 이전 예는 b(?<Word>w+)bs+k<Word>b와 같이 작성할 수도 있습니다.
괄호를 사용할 때 특수 용도의 구문이 많이 있습니다. 가장 일반적으로 사용되는 구문은 다음과 같습니다.
표 4. 일반적인 그룹화 구문
너비 없음 어설션
지구인 여러분, 이 용어와 명칭이 너무 복잡하고 기억하기 어렵다고 생각하시나요? 나도 같은 느낌이다. 그런 것이 있다는 것만 알아두세요. 이름이 무엇인지, 놓아주세요! 이름이 없으면 검술에 집중할 수 있고, 이름이 없으면 마음대로 선택할 수 있습니다...
다음 4개는 특정 내용의 앞이나 뒤를 찾는 데 사용됩니다(단, 이름이 없으면 이러한 내용 포함) 즉, 특정 조건(예: 어설션)을 만족해야 하는 위치를 지정하기 위해 b,^,$와 같이 사용되므로 너비가 0인 어설션이라고도 합니다. 예시를 사용하여 설명하는 것이 가장 좋습니다.
주장은 사실이어야 하는 사실을 선언하는 데 사용됩니다. 정규식 일치는 어설션이 true인 경우에만 계속됩니다.
(?=exp)는 너비가 0인 긍정적 예측 어설션이라고도 하며 exp가 나타나는 위치 다음에 표현식이 일치할 수 있음을 나타냅니다. 예를 들어, bw+(?=ingb)는 ing(ing 제외)으로 끝나는 단어의 앞부분과 일치합니다. 예를 들어 I'm sing while you's dance.를 검색하면 sing 및 dance와 일치합니다.
(?<=exp)는 너비가 0인 긍정적인 사후 조회 어설션이라고도 하며 이전 위치가 exp 표현식과 일치할 수 있다고 주장합니다. 예를 들어, (?<=bre)w+b는 re(re 제외)로 시작하는 단어의 후반부와 일치합니다. 예를 들어, reading a book을 검색하면 ading과 일치합니다.
매우 긴 숫자(물론 오른쪽부터 추가)에서 세 자리마다 쉼표를 추가하고 싶다면 앞뒤로 쉼표를 추가해야 하는 부분을 다음과 같이 찾으면 됩니다. ((( ?<=d)d{3})+b, 1234567890을 검색하는 데 사용하면 결과는 234567890입니다.
다음 예에서는 두 가지 어설션을 모두 사용합니다. (?<=s)d+(?=s)는 공백 문자로 구분된 숫자와 일치합니다(이러한 공백 문자는 포함되지 않음).
음수 0 너비 어설션
앞서 특정 문자가 아니거나 특정 문자 클래스에 속하지 않는 문자를 찾는 방법을 언급했습니다. 방법(반의어). 하지만 특정 문자가 나타나지 않도록 하고 싶지만 일치시키고 싶지 않은 경우에는 어떻게 해야 할까요? 예를 들어, 문자 q가 나타나지만 q 뒤에 문자 u가 없는 단어를 찾고 싶다면 다음과 같이 시도해 볼 수 있습니다.
bw*q[^u]w*b는 문자 u가 아닌 문자 q가 뒤에 오는 단어를 포함합니다. 하지만 좀 더 테스트해 보면(또는 생각이 충분히 예리하다면 직접 관찰할 수 있음) 이라크, Benq처럼 단어 끝에 q가 나타나면 이 표현이 잘못된다는 것을 알게 될 것입니다. 이는 [^u]가 항상 하나의 문자와 일치하기 때문입니다. 따라서 q가 단어의 마지막 문자인 경우 다음 [^u]는 q 뒤의 단어 구분 기호(공백, 마침표 또는 기타 무엇일 수 있음)와 일치합니다. 다음 w*b는 다음 단어와 일치하므로 bw*q[^u]w*b는 전체 이라크 전투와 일치할 수 있습니다. 너비가 0인 부정 어설션은 한 위치에만 일치하고 문자를 사용하지 않기 때문에 이 문제를 해결할 수 있습니다. 이제 이 문제를 다음과 같이 해결할 수 있습니다: bw*q(?!u)w*b.
너비가 0인 부정 예측 어설션(?!exp)은 표현식 exp가 이 위치 이후에 일치할 수 없다고 어설션합니다. 예를 들어, d{3}(?!d)는 세 자리 숫자와 일치하며, 이 세 자리 뒤에는 숫자가 올 수 없습니다. b((?!abc)w)+b는 연속 문자열 abc를 포함하지 않는 단어와 일치합니다.
마찬가지로 너비가 0인 부정 되돌아보기 어설션인 (?<!exp)를 사용하여 이전 위치가 exp 표현식과 일치할 수 없다고 주장할 수 있습니다. (?<![a-z])d{ 7 } 앞에 소문자가 없는 7자리 숫자와 일치합니다.
(?<=<(w+)>).*(?=</1>) 표현식을 자세히 분석해 보세요. 이 표현식은 너비가 0인 어설션의 진정한 목적을 가장 잘 표현합니다.
더 복잡한 예: (?<=<(w+)>).*(?=</1>)는 속성을 포함하지 않는 간단한 HTML 태그 내부의 콘텐츠와 일치합니다. (<?(w+)>)는 접두사를 지정합니다. 즉, 꺾쇠 괄호로 묶인 단어(예: <b>), .*(임의 문자열), 마지막으로 접미사(? =<)를 지정합니다. ;/1>). 앞에서 언급한 문자 이스케이프를 사용하는 접미사의 /에 주의하세요. 1은 캡처된 첫 번째 그룹을 참조하는 역참조이고, 이전(w+)과 일치하는 내용이므로 실제로 접두사는 다음과 같습니다. , 접미사는 입니다. 전체 표현식은 <b>와 </b> 사이의 내용과 일치합니다(역시 접두사와 접미사 자체는 포함하지 않음).
댓글
괄호의 또 다른 용도는 구문(?#comment)을 통해 댓글을 포함하는 것입니다. 예: 2[0-4]d(?#200-249)|25[0-5](?#250-255)|[01]?dd?(?#0-199).
주석을 포함하려면 "패턴에서 공백 문자 무시" 옵션을 활성화하는 것이 가장 좋습니다. 그러면 표현식을 작성할 때 공백, 탭, 줄 바꿈을 임의로 추가할 수 있지만, 다음에서는 이러한 항목이 무시됩니다. 실제 사용. 이 옵션을 활성화하면 # 다음에 줄 끝까지의 모든 텍스트가 주석으로 무시됩니다. 예를 들어 이전 표현식을 다음과 같이 작성할 수 있습니다.
(?<= # 断言要匹配的文本的前缀 <(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签) ) # 前缀结束 .* # 匹配任意文本 (?= # 断言要匹配的文本的后缀 <\/> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签 ) # 后缀结束
탐욕과 게으름
정규 표현식에 반복이 포함된 경우 한정자를 지정하는 경우 에서 일반적인 동작은 가능한 한 많은 문자를 일치시키는 것입니다(여전히 전체 표현식이 일치하도록 허용하면서). 예를 들어 a.*b 표현식을 사용하면 a로 시작하고 b로 끝나는 가장 긴 문자열과 일치합니다. 이를 사용하여 aabab을 검색하면 전체 문자열 aabab과 일치합니다. 이를 탐욕스러운 일치라고 합니다.
때때로 지연 매칭, 즉 가능한 한 적은 수의 문자를 매칭해야 하는 경우도 있습니다. 위에 제공된 한정자는 뒤에 물음표 ?를 추가하여 지연 일치 패턴으로 변환할 수 있습니다. 이런 방식으로 .*?는 임의의 반복 횟수를 일치시키되 전체 일치를 성공시키려면 최소한의 반복을 사용함을 의미합니다. 이제 예제의 게으른 버전을 살펴보십시오.
a.*?b는 a로 시작하고 b로 끝나는 가장 짧은 문자열과 일치합니다. aabab에 적용하면 aab(첫번째~세번째 문자), ab(네번째~다섯번째 문자)와 일치하게 됩니다.
첫 번째 일치 항목이 ab(두 번째~세 번째 문자) 대신 aab(첫 번째~세 번째 문자)인 이유는 무엇인가요? 간단히 말해서, 정규식에는 게으른/탐욕적인 규칙보다 우선순위가 더 높은 또 다른 규칙이 있기 때문에 가장 먼저 시작하는 일치가 가장 높은 우선순위를 갖습니다. 즉, 가장 먼저 시작하는 일치가 승리합니다.
표 5. 지연 한정자
처리 옵션
C#에서는 Regex(String, RegexOptions) 생성자를 사용하여 정규식 처리 옵션을 설정할 수 있습니다. 예: Regex regex = new Regex(@"baw{6}b", RegexOptions.IgnoreCase);
위에서는 대소문자 무시, 여러 줄 처리 등 여러 옵션을 소개합니다. 이러한 옵션을 사용할 수 있습니다. 정규식을 처리하는 방법을 변경하려면 다음은 .Net에서 일반적으로 사용되는 정규식 옵션입니다.
표 6. 일반적으로 사용되는 처리 옵션
자주 묻는 질문은 다음과 같습니다. 예 멀티라인 모드와 싱글라인 모드 중 하나만 동시에 사용할 수는 없나요? 대답은: 아니오입니다. 이름이 혼동될 정도로 유사하다는 점을 제외하면 이 두 옵션 사이에는 아무런 관계가 없습니다.
균형 그룹/재귀적 일치
여기에 소개된 균형 그룹 구문은 .Net Framework에서 반드시 지원되는 것은 아닙니다. 지원 이 기능은 지원될 수 있지만 다른 구문이 필요합니다.
(100 * (50 + 15))과 같은 중첩 가능한 계층 구조를 일치시켜야 하는 경우가 있습니다. 이 경우 간단히 (.+)를 사용하면 가장 왼쪽의 왼쪽 대괄호와 가장 오른쪽 닫는 부분 사이의 내용만 일치합니다. 대괄호(여기서는 그리디 모드에 대해 논의하고 있으며, 게으른 모드에도 다음과 같은 문제가 있습니다). (5 / (3 + 2)))와 같이 원래 문자열에서 왼쪽 대괄호와 오른쪽 대괄호의 발생 횟수가 동일하지 않으면 일치 결과에서 두 대괄호의 수가 동일하지 않습니다. 그러한 문자열에서 대괄호 사이에 가장 길고 일치하는 내용을 일치시킬 수 있는 방법이 있습니까?
( 및 ( 머리가 완전히 혼란스러워지는 것을 방지하기 위해 둥근 괄호 대신 꺾쇠 괄호를 사용하겠습니다. 이제 우리의 질문은 다음과 같은 문자열에서 xx
여기에서는 다음 구문 구조를 사용해야 합니다.
(?'group') 캡처된 콘텐츠의 이름은 group이고 스택에 푸시됨(Stack)
(?'-group') 스택에서 마지막으로 푸시된 그룹이라는 캡처된 콘텐츠를 팝합니다. 스택이 원래 비어 있으면 이 그룹의 일치가 이루어집니다. failed
(?(group)yes|no) 스택에 group이라는 캡처 콘텐츠가 있으면 yes 부분의 표현을 계속 일치시키고, 그렇지 않으면 no 부분을 계속 일치합니다
(?!) 너비가 0인 부정 예측 어설션, 접미사 표현식이 없기 때문에 일치 시도는 항상 실패합니다
프로그래머가 아닌 경우(또는 자신을 프로그래머라고 부르지만 스택이 무엇인지 모르는 경우) is) , 위의 세 가지 구문을 다음과 같이 이해할 수 있습니다. 첫 번째는 칠판에 "그룹"을 쓰는 것이고, 두 번째는 칠판에서 "그룹"을 지우는 것이며, 세 번째는 칠판에 적힌 내용을 읽는 것입니다. "그룹"이 없으면 계속해서 yes 부분을 일치시키고, 그렇지 않으면 no 부분을 일치시킵니다.
우리가 해야 할 일은 왼쪽 대괄호를 만날 때마다 "Open"을 푸시하고, 오른쪽 대괄호를 만날 때마다 하나씩 팝업한 다음, 마지막에 스택이 비어 있는지 확인하는 것입니다. 비어 있지 않은 경우 , 그런 다음 오른쪽 괄호보다 왼쪽 괄호가 더 많다는 것을 증명하므로 일치가 실패해야 합니다. 정규식 엔진은 역추적(첫 번째 또는 마지막 문자 중 일부 삭제)하고 전체 표현식을 일치시키려고 시도합니다.
< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号的内容 ( ( (?'Open'<) #碰到了左括号,在黑板上写一个"Open" [^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?'-Open'>) #碰到了右括号,擦掉一个"Open" [^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败 > #最外层的右括号
균형 그룹의 가장 일반적인 적용 중 하나는 HTML을 일치시키는 것입니다. 다음 예는 중첩된 <div> 태그를 일치시킬 수 있습니다: <div[^>]*>[^<> ]*(((?'열기'<div[^>]*>)[^<]*)+((?'-열기'</div>)[^<> ]*)+)*(?(Open)(?!))</div>.
또 언급되지 않은 내용이 있습니다
정규식을 구성하기 위한 많은 요소에 대해 위에서 설명했지만, 아직 언급되지 않은 부분이 많습니다. 아래에는 언급되지 않은 일부 요소의 목록과 구문 및 간단한 설명이 나와 있습니다. 필요할 때 자세한 내용을 알아보려면 온라인에서 더 자세한 참고 자료를 찾아보세요. MSDN Library를 설치한 경우 .net에서 정규식에 대한 자세한 설명서를 찾을 수도 있습니다.
여기서 소개하는 내용은 매우 간단합니다. 더 자세한 정보가 필요하고 컴퓨터에 MSDN Library가 설치되어 있지 않은 경우 정규식 언어 요소에 대한 MSDN 온라인 설명서를 볼 수 있습니다.
표 7. 아직 자세히 논의되지 않은 구문