06 정규식 - 교체 / 그룹화 / 역참조 🕔 2014. 12. 11. 16:24
출처 : MSDN Library
Visual Studio 2005 & Visual Studio 2008 & Visual Studio 2010 을 종합한 내용이며,
흐린 색으로 표시된, 괄호() 안의 내용은 개인적으로 덧붙인 사족입니다. ^^*
어려운 말이 등장하는데, 사족이 없다면 "아,,, 얘도 모르는구나,,," 하시면 됩니다. ㅡ.ㅡ;;
제가 잘못 이해하고 있는 부분이 있다면 댓글을 달아 주십시오. 그런 지적질(?)은 언제나 환영입니다. *^^*
교체 및 그룹화 (Visual Studio 2005 & Visual Studio 2008)
교체 시에는 | 문자를 사용하여 두 개 이상의 대안 중에서 한 가지를 선택할 수 있습니다.
(여기서 쓰이는 |' 를 파이프 문자라 부릅니다)
예를 들어, 장 제목 정규식을 확장하여 장 제목 이외의 내용을 반환할 수 있습니다.
하지만 이러한 작업은 생각만큼 간단하지 않습니다.
교체에서는 | 문자의 양쪽에서 가장 큰 식을 찾습니다.
다음 식에서는, 줄의 시작 부분과 끝 부분에서
Chapter나 Section 다음에, 한 자리 또는 두 자리 숫자가 나타나는 항목을 찾는 것으로 생각할 수 있습니다.
/^Chapter|Section [1-9][0-9]{0,1}$/
하지만 아쉽게도 위의 정규식에서는, 줄의 시작 부분에서 Chapter만 찾거나
Section 단어와 줄의 끝 부분에서, Section 다음에 오는 숫자만 찾습니다.
입력 문자열이 Chapter 22이면, 위의 식에서는 Chapter 단어만 찾습니다.
입력 문자열이 Section 22이면, 위의 식에서는 Section 22를 찾습니다.
정규식의 응답성을 향상시키려면, 교체 범위를 제한하기 위해
즉, 교체가 Chapter와 Section 단어 두 곳에만 적용됨을 확실히 하기 위해서 괄호를 사용할 수 있습니다.
하지만, 부분식을 만들고서 역참조 단원에서 다루게 될 용도로
나중에 사용할 수 있도록 부분식을 캡처하기 위해서, 괄호를 사용할 수도 있습니다.
위의 정규식에서 적절한 위치에 괄호를 추가하여, Chapter 1이나 Section 3을 찾을 정규식을 만들 수 있습니다.
다음 정규식에서는 괄호를 사용하여 Chapter와 Section을 그룹화하였으므로, 해당 식이 바르게 작동합니다.
/^(Chapter|Section) [1-9][0-9]{0,1}$/
이러한 식은 제대로 작동하지만, Chapter|Section 주위의 괄호는
두 개의 일치하는 단어 중 하나를, 나중에 사용할 수 있도록 캡처합니다.
위의 식에서는, 괄호가 한 세트만 있으므로, 캡처된 부분 일치는, 하나만 생깁니다.
이러한 부분 일치는, RegExp 개체의 $1-$9 속성을 사용하여, 참조될 수 있습니다.
위의 예제에서, Chapter와 Section 단어 사이의 선택을, 그룹화하기 위해, 괄호를 사용할 수도 있습니다.
나중에 사용할 수 있도록, 일치가 저장되는 것을 막으려면, 괄호 내부의 정규식 패턴 앞에, ?:을 넣습니다.
다음과 같이 수정하면, 부분 일치를 저장하지 않고 같은 기능을 제공하게 됩니다.
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/
?: 메타문자 이외에 다른 두 개의 비캡처링 메타문자도 미리 보기 일치라는 것을 만듭니다.
?=을 사용하여 지정된 양의 미리 보기(긍정형 전방 탐색)는
괄호 안의 일치하는 정규식 패턴이 시작하는 지점에서 검색 문자열을 찾습니다.
?!을 사용하여 지정된 음의 미리 보기(부정형 전방 탐색)에서는
정규식 패턴과 일치하지 않는 문자열이 시작하는 지점에서 검색 문자열을 찾습니다.
예를 들어,
Windows 3.1과 Windows 95, Windows 98 및 Windows NT에 대한 참조가 포함된
문서가 있다고 가정합니다.
그리고 Windows 95, Windows 98 및 Windows NT에 대한 모든 참조를
Windows 2000으로 변경하여, 문서를 업데이트해야 할 필요가 있다고 가정합니다.
양의 미리 보기의 예제인
다음 정규식에서는 Windows 95, Windows 98 및 Windows NT를 찾습니다.
/Windows(?=95 |98 |NT )/
일단 일치 항목을 찾으면, 미리 보기의 문자를 포함하지 않고
찾은 텍스트 뒷부분부터, 다음 일치 항목에 대한 검색이 바로 시작됩니다.
예를 들어, 위의 식에서 Windows 98을 찾았으면, 98이 아닌 Windows 다음에서 검색이 다시 시작됩니다.
역참조 (Visual Studio 2005 & Visual Studio 2008)
정규식의 가장 중요한 기능은, 일치하는 패턴의 일부를, 나중에 다시 사용하기 위해서, 저장하는 기능입니다.
이미 알고 있듯이, 정규식 패턴이나 패턴의 일부를, 괄호로 묶으면, 식의 일부가 임시 버퍼에 저장됩니다.
비캡처링 메타문자인, ?:나 ?= 또는 ?!를 사용하여, 캡처를 재정의할 수 있습니다.
캡처된 부분 일치는 정규식 패턴에서, 왼쪽으로 오른쪽으로, 발견된 순서대로 저장됩니다.
버퍼 수는, 캡처된 부분 일치의, 1에서 시작하여 99까지 계속됩니다.
각 버퍼는, \n을 사용하여, 액세스할 수 있는데
여기서 n은, 특정 버퍼를 식별하는, 한 자리 또는 두 자리의 10진수입니다.
역참조의 가장 단순하고 유용한 응용 프로그램 중 하나는
텍스트에서 두 개의 동일한 인접 단어의 사용을 찾는 기능을 제공합니다.
다음 문장을 사용해 봅니다.
Is is the cost of of gasoline going up up?
위의 문장에는 분명히 여러 개의 중복된 단어가 있습니다.
단어마다 중복된 내용은 찾지 않도록, 해당 문장을 수정할 수 있는 방법이 있으면 좋을 것입니다.
다음 정규식에서는 그러한 작업을 위해 단일 부분식을 사용합니다.
/\b([a-z]+) \1\b/gi
[a-z]+에서 지정한 대로 캡처된 식은, 하나 이상의 영문자를 포함합니다.
정규식의 두 번째 부분은 앞에서 캡처된 부분 일치 즉,
괄호 식에서 찾은 단어의
두 번째 사용에 대한 참조입니다.
\1은 첫 번째 부분 일치를 지정합니다.
단어 경계 메타문자는, 단어 단위로만 찾게 합니다.
그렇지 않은 경우, "is issued"나 "this is"와 같은 구는 이 식에 의해서 잘못 식별될 수 있습니다.
정규식 다음에 오는, global 플래그(g)는
입력 문자열에서 찾을 수 있는 일치 항목에 적용될 수 있는 식을 나타냅니다.
식의 끝에 있는 대/소문자를 구분하지 않음(i) 플래그는
대/소문자를 구분하지 않음을 지정합니다.
여러 줄 입력 가능한 플래그는, 줄 바꿈 문자의 어느 쪽에서나 잠재적 일치가 나타날 수 있음을 지정합니다.
위의 정규식을 사용하면서 다음 코드에서는, 부분 일치 정보를 사용하여
텍스트 문자열에서, 연속적으로 같은 단어가 두 개 사용한 것을, 동일한 단어의 단일 사용으로 바꿀 수 있습니다.
var ss = "Is is the cost of of gasoline going up up?.\n"; var re = /\b([a-z]+) \1\b/gim; //Create regular expression pattern. var rv = ss.replace(re,"$1"); //Replace two occurrences with one.
replace 메서드 내에서 $1을 사용하면, 처음으로 저장된 부분 일치를 참조합니다.
부분 일치가 여러 개 있으면, $2, $3 등을 사용하여 연속적으로 부분 일치를 참조할 수 있습니다.
역참조를 사용하면, URI(Universal Resource Indicator)를 해당 구성 요소별로 나눌 수 있습니다.
다음 URI를 " 프로토콜(ftp, http 등), 도메인 주소, 페이지/경로 " 로 구분한다고 가정합니다.
http://msdn.microsoft.com:80/scripting/default.htm
다음 정규식에서는 그러한 기능을 제공합니다.
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
1. 처음에 나온 괄호의 부분식은 웹 주소의 프로토콜 부분을 캡처합니다.
해당 부분식에서는 콜론과 두 개의 슬래시 앞에 오는 단어를 찾습니다.
2. 두 번째 괄호의 부분식은 해당 주소의 도메인 주소를 캡처합니다.
해당 부분식에서는 / 또는 :가 아닌 하나 이상의 문자를 찾습니다.
3. 세 번째 괄호의 부분식은, 포트 번호가 지정되어 있으면 포트 번호를 캡처합니다.
해당 부분식에서는 콜론 다음에 오는 0개 이상의 숫자를 찾습니다.
이 부분식은 한 번만 반복할 수 있습니다.
4. 마지막으로 네 번째 괄호의 부분식은 웹 주소에서 지정한 경로 및/또는 페이지 정보를 캡처합니다.
해당 부분식에서는 #이나 공백 문자가 포함되지 않은 문자의 시퀀스를 찾습니다.
위의 URI에 정규식을 적용하면 부분 위치에 다음 내용이 포함됩니다.
- RegExp.$1에는 "http"가 포함됩니다.
- RegExp.$2에는 "msdn.microsoft.com"이 포함됩니다.
- RegExp.$3에는 ":80"이 포함됩니다.
- RegExp.$4에는 "/scripting/default.htm"이 포함됩니다.
교체 및 부분식 (Visual Studio 2010)
정규식에서 교체를 사용하면 둘 이상의 대체 항목 간 선택을 그룹화할 수 있습니다.
즉, 기본적으로 패턴에서 "this OR that"을 지정할 수 있습니다.
하위 식을 사용하면 검색된 텍스트에서 패턴을 찾아 일치 항목을 여러 개의 부분 일치로 분할할 수 있습니다.
이에 따른 부분 일치는 프로그램에 의해 검색될 수 있습니다.
또한 하위 식을 통해 JScript의 역참조에 설명된 대로 텍스트의 형식을 다시 지정할 수 있습니다.
교체
파이프(|) 문자를 사용하여 둘 이상의 대체 항목 중에 선택하도록 지정할 수 있습니다.
이를 교체라고 합니다.
교체에서는 | 문자의 양쪽에서 가장 큰 식을 찾습니다.
다음 정규식은 1개 또는 2개의 숫자 앞에 있는 "Chapter" 또는 "Section"을 찾을 것으로 생각될 수도 있습니다.
/Chapter|Section [1-9][0-9]{0,1}/
그러나 이 정규식은 단어 "Chapter" 또는 단어 "Section"과 그 뒤에 있는 모든 숫자를 찾습니다.
검색되는 문자열이 "Section 22"이면 해당 식에서는 "Section 22"를 찾습니다.
그러나 검색되는 문자열이 "Chapter 22"이면 해당 식에서는 "Chapter 22"가 아니라 단어 "Chapter"를 찾습니다.
괄호를 사용한 교체
괄호를 사용해 교체 범위를 제한하여, 두 단어 "Chapter"와 "Section"에만 적용되도록 할 수 있습니다.
괄호를 추가하면 정규식에서 "Chapter 1" 또는 "Section 3"을 찾도록 할 수 있습니다.
그러나 괄호는 하위 식을 만드는 데도 사용됩니다.
이에 따른 부분 일치는 프로그램에 의해 검색될 수 있습니다.
다음 JScript 정규식에서는 괄호를 사용하여, "Chapter"와 "Section"을 그룹화합니다.
이 정규식은 "Chapter"와 그 뒤의 숫자를 찾게 됩니다.
/(Chapter|Section) [1-9][0-9]{0,1}/
또한 Chapter|Section을 둘러싼 괄호는, 일치하는 두 단어 중 하나가 향후 사용을 위해 저장되도록 합니다.
다음 예제는 일치 및 부분 일치를 코드에서 검색할 수 있는 방법을 보여 줍니다.
이 식에서는 괄호가 한 세트만 있으므로 하나의 부분 일치만 저장됩니다.
var re = /(Chapter|Section) [1-9][0-9]{0,1}/g var src = "Chapter 50 Section 85" ShowMatches(src, re); // Output: // Chapter 50 // submatch 1: Chapter // Section 85 // submatch 1: Section // Perform a search on a string by using a regular expression, // and display the matches and submatches. function ShowMatches(src, re){ var result; // Get the first match. result = re.exec(src); while (result != null){ // Show the entire match. print(); print(result[0]); // Show the submatches. for (var index=1; index<result.length; index++){ print("submatch " + index + ": " + result[index]); } // Get the next match. result = re.exec(src); } }
저장되는 부분 일치 없는 교체
앞의 예제에서 단어 "Chapter"와 "Section" 사이의 선택을 그룹화하기 위해 괄호를 사용할 수도 있습니다.
나중에 사용하기 위해 부분 일치가 저장되지 않도록 하려면 (?:pattern) 하위 식을 지정하면 됩니다.
다음 예제에서는 이전 예제와 동일한 작업을 수행하지만 부분 일치를 저장하지는 않습니다.
var re = /(?:Chapter|Section) [1-9][0-9]{0,1}/g;
var src = "Chapter 50 Section 85";
ShowMatches(src, re);
// Output:
// Chapter 50
// Section 85
하위 식
정규식에서 괄호를 사용하면 하위 식이 만들어집니다.
이에 따른 부분 일치는 프로그램에 의해 검색될 수 있습니다.
다음 예제의 정규식에는 하위 식 3개가 포함되어 있습니다.
부분 일치 문자열은 각 일치 문자열과 함께 표시됩니다.
var re = /(\w+)@(\w+)\.(\w+)/g;
var src = "Please send mail to george@contoso.com and someone@example.com. Thanks!";
ShowMatches(src, re);
// The ShowMatches function is provided earlier.
// Output:
// george@contoso.com
// submatch 1: george
// submatch 2: contoso
// submatch 3: com
// someone@example.com
// submatch 1: someone
// submatch 2: example
// submatch 3: com
다음 예제는 URI(Universal Resource Indicator)를 여러 개의 구성 요소 부분으로 분리합니다.
처음에 나온 괄호의 하위 식은 웹 주소의 프로토콜 부분을 저장합니다.
이 하위 식에서는 콜론과 두 개의 슬래시 앞에 오는 단어를 찾습니다.
두 번째 괄호의 하위 식은 해당 주소의 도메인 주소를 저장합니다.
이 하위 식에서는 슬래시 표시(/) 또는 콜론(:)이 포함되지 않은 문자의 시퀀스를 찾습니다.
세 번째 괄호의 하위 식은 포트 번호가 지정되어 있으면 웹 사이트 포트 번호를 저장합니다.
이 하위 식에서는 콜론 뒤에 오는 0개 이상의 숫자를 찾습니다.
네 번째 괄호의 하위 식은 웹 주소에서 지정한 경로 및/또는 페이지 정보를 저장합니다.
이 하위 식에서는 번호 기호 문자(#) 또는 공백 문자가 아닌 0개 이상의 문자를 찾습니다.
var re = /(\w+):\/\/([^\/:]+)(:\d*)?([^# ]*)/gi;
var src = "http://msdn.microsoft.com:80/scripting/default.htm";
ShowMatches(src, re);
// Output:
// http://msdn.microsoft.com:80/scripting/default.htm
// submatch 1: http
// submatch 2: msdn.microsoft.com
// submatch 3: :80
// submatch 4: /scripting/default.htm
양성 및 음성 Lookahead
양성 lookahead(미리보기)는 일치하는 텍스트가 발견된 후 이 텍스트 앞에서 다음 일치 텍스트를 찾기 시작하는 검색입니다.
일치 항목은 나중에 사용하기 위해 저장되지 않습니다. 양성 lookahead를 지정하려면 (?=pattern) 구문을 사용하십시오.
다음 예제에서는 암호 길이가 4글자에서 8글자이고 암호에 하나 이상의 숫자가 포함되어 있는지 여부를 확인하기 위해 검색이 수행됩니다.
이 정규식에서 .*\d는 임의 개수의 문자와 그 다음에 숫자가 오는 경우를 찾습니다.
검색되는 문자열이 "abc3qr"일 때 이는 "abc3"과 일치합니다.
.{4,8}은 일치 항목의 뒤가 아니라 앞에서 시작해서 4-8개의 문자열을 찾습니다.
이는 "abc3qr"과 일치합니다.
^ 및 $는 검색되는 문자열의 시작 및 끝에서 위치를 지정합니다.
이는 검색된 문자열에 일치된 문자 밖의 문자가 포함되어 있으면 일치하지 않는 것으로 하기 위한 것입니다.
var re = /^(?=.*\d).{4,8}$/gi;
var src = "abc3qr";
ShowMatches(src, re);
// The ShowMatches function is provided earlier.
// Output:
// abc3qr
음성 lookahead(미리보기)는 음성 lookahead 식의 패턴과 일치하지 않는 검색 문자열을 검색합니다.
일치 항목을 찾은 후 일치한 텍스트의 앞에서 다음 일치 항목에 대한 검색을 시작합니다.
일치 항목은 나중에 사용하기 위해 저장되지 않습니다.
음성 lookahead를 지정하려면 (?!pattern) 구문을 사용하십시오.
다음 예제는 "th"로 시작하지 않는 단어를 찾습니다.
이 정규식에서 \b는 단어 경계를 찾습니다.
검색되는 문자열이 " quick "일 때 이는 첫 번째 공백과 일치합니다.
(?!th)는 "th"가 아닌 문자열을 찾습니다. 이는 "qu"와 일치합니다.
\w+는 일치 항목의 앞에서 단어를 검색합니다. 이는 "quick"과 일치합니다.
var re = /\b(?!th)\w+\b/gi;
var src = "The quick brown fox jumps over the lazy dog.";
ShowMatches(src, re);
// Output:
// quick
// brown
// fox
// jumps
// over
// lazy
// dog
역참조 (Visual Studio 2010)
역참조는 문자의 반복 그룹을 찾는 데 사용됩니다.
또한 입력 문자열에서 요소의 순서 및 배치를 조정하여 입력 문자열의 형식을 다시 지정하는 데도 사용됩니다.
하위 식은 정규식 및 대체 문자열 내에서 참조할 수 있습니다.
각 하위 식은 번호로 식별되며 역참조라고 합니다.
괄호는 하위 식을 만들기 위해 정규식에서 사용됩니다.
이에 따른 부분 일치는 프로그램에 의해 검색될 수 있습니다.
역참조 사용
하위 식은 정규식 내에서 참조할 수 있습니다.
정규식에서 저장된 각 부분 일치는 왼쪽으로 오른쪽으로 발견된 순서대로 저장됩니다.
부분 일치가 저장되는 버퍼 수는 하위 식의 1에서 시작하여 99까지 계속됩니다.
정규식 내에서 \n을 사용하여 각 버퍼에 액세스할 수 있는데
여기서 n은 특정 버퍼를 식별하는 한 자리 또는 두 자리 10진수입니다.
역참조의 응용 사례 중 하나는 텍스트에서 두 개의 동일한 인접 단어를 찾는 기능을 제공합니다.
다음 문장을 사용해 봅니다.
Is is the cost of of gasoline going up up?
위의 문장에는 여러 개의 중복된 단어가 있습니다.
단어마다 중복된 내용은 찾지 않도록 해당 문장을 수정할 수 있는 방법이 있으면 좋을 것입니다.
다음 정규식에서는 그러한 작업을 위해 단일 하위 식을 사용합니다.
/\b([a-z]+) \1\b/gi
이 경우 하위 식은 괄호로 둘러싸인 모든 부분이 해당됩니다.
이 하위 식은 [a-z]+에서 지정한 대로 하나 이상의 영문자를 포함합니다.
정규식의 두 번째 부분은 앞에서 저장된 부분 일치 즉,
괄호 식에서 찾은 단어의 두 번째 사용에 대한 참조입니다.
이때 \1은 첫 번째 부분 일치를 지정하는 데 사용됩니다.
\b 단어 경계 메타문자는 개별 단어 단위로만 찾게 합니다.
그렇지 않은 경우 "is issued"나 "this is"와 같은 구는 이 식에 의해 잘못 식별될 수 있습니다.
다음 예제는 중복된 단어를 나열합니다.
이 예제는 일치 및 부분 일치를 코드에서 검색할 수 있는 방법을 보여 줍니다.
var result; var re = /\b([a-z]+) \1\b/gi; var src = "Is is the cost of of gasoline going up up?"; // Get the first match. result = re.exec(src); while (result != null){ // Show the entire match. print(); print(result[0]); // Show the submatches. for (var index = 1; index < result.length; index++){ print("submatch " + index + ": " + result[index]); } // Get the next match. result = re.exec(src); } // Output: // Is is // submatch 1: Is // of of // submatch 1: of // up up // submatch 1: up
하위 식은 대체 문자열 내에서도 참조할 수 있습니다.
위에 나온 정규식을 사용할 경우 다음 예제는 연속되는 두 개의 동일 단어를 같은 단어 1개로 바꿉니다.
replace 메서드에서 $1은 저장된 첫 번째 부분 일치를 가리킵니다.
부분 일치가 여러 개 있으면 $2, $3 등을 사용하여 연속적으로 부분 일치를 참조할 수 있습니다.
var re = /\b([a-z]+) \1\b/gi;
var src = "Is is the cost of of gasoline going up up?";
var result = src.replace(re, "$1");
print(result);
// Output:
// Is the cost of gasoline going up?
다음 예제에서는 문자열의 각 단어 쌍을 바꿉니다.
var re = /(\S+)(\s+)(\S+)/gi;
var src = "The quick brown fox jumps over the lazy dog.";
var result = src.replace(re, "$3$2$1");
print(result);
// Output:
// quick The fox brown over jumps lazy the dog.
이 내용이 도움이 되셨다면, 아래의 하트 버튼을 눌러주세요. *^^*
'정규식 (정규표현식) > MSDN Library' 카테고리의 다른 글
05 정규식 - 앵커 (0) | 2014.12.11 |
---|---|
04 정규식 - 수량자 (0) | 2014.12.11 |
03 정규식 - 문자 일치 (0) | 2014.12.11 |
02 정규식 - 문자의 종류 (0) | 2014.12.11 |
01 정규식의 개념 (0) | 2014.12.11 |