도입

정규식 (正規式, Regular Expression)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어입니다. 이걸 잘 써야 당장 코드 라인이 줄겠죠. 지금부터 정규식 사용법을 구체적으로 알아보고, 활용 방안의 예시를 베껴서 기록하고자 합니다.

정규식 쓰임

    • PHP의 preg_match 함수
      • $subject = "abcdef";
        $pattern = '/^def/';
        preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
        print_r($matches);
        
    • C#의 RegEx 클래스
      • class TestRegularExpressionValidation
        {
            static void Main()
            {
                string[] numbers = 
                {
                    "123-555-0190", 
                    "444-234-22450", 
                    "690-555-0178", 
                    "146-893-232",
                    "146-555-0122",
                    "4007-555-0111", 
                    "407-555-0111", 
                    "407-2-5555", 
                };
        
                string sPattern = "^\d{3}-\d{3}-\d{4}$";
        
                foreach (string s in numbers)
                {
                    System.Console.Write("{0,14}", s);
        
                    if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern))
                    {
                        System.Console.WriteLine(" - valid");
                    }
                    else
                    {
                        System.Console.WriteLine(" - invalid");
                    }
                }
        
                // Keep the console window open in debug mode.
                System.Console.WriteLine("Press any key to exit.");
                System.Console.ReadKey();
            }
        }
        /* Output:
              123-555-0190 - valid
             444-234-22450 - invalid
              690-555-0178 - valid
               146-893-232 - invalid
              146-555-0122 - valid
             4007-555-0111 - invalid
              407-555-0111 - valid
                407-2-5555 - invalid
        */
    • Java의 RegEx 클래스
      • import java.util.regex.Matcher;
        import java.util.regex.Pattern;
        
        public class RegexMatches {
        
           public static void main( String args[] ) {
              // String to be scanned to find the pattern.
              String line = "This order was placed for QT3000! OK?";
              String pattern = "(.*)(\d+)(.*)";
        
              // Create a Pattern object
              Pattern r = Pattern.compile(pattern);
        
              // Now create matcher object.
              Matcher m = r.matcher(line);
              if (m.find( )) {
                 System.out.println("Found value: " + m.group(0) );
                 System.out.println("Found value: " + m.group(1) );
                 System.out.println("Found value: " + m.group(2) );
              }else {
                 System.out.println("NO MATCH");
              }
           }
        }
  • javascript 리터럴 또는 RegExp 클래스
    • var myRe = /d(b+)d/g;
      var myArray = myRe.exec("cdbbdbsbz");
  • URL Rewrite Rule
    • rewrite ^/blog/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/blog/sitemap$2.xml" last;
      rewrite ^/blog/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/blog/index.php?xml_sitemap=params=$2" last;
      rewrite ^/blog/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/blog/index.php?xml_sitemap=params=$2;zip=true" last;
      rewrite ^/blog/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/blog/index.php?xml_sitemap=params=$2;html=true" last;
      rewrite ^/blog/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/blog/index.php?xml_sitemap=params=$2;html=true;zip=true" last;

정규식 레퍼런스

문자열 클래스
[문자열] 문자열에서 발견된 모든 문자가 선택됩니다. (한 글자) 예시보기
[^문자열] 문자열에서 발견되지 않은 나머지 문자가 선택됩니다. 예시보기
[처음] 처음에서 끝까지의 범위 안 모든 문자가 해당됩니다. 예시보기
. 와일드카드. \n을 제외한 모든 문자가 선택됩니다. 예시보기
\p{카테고리} 유니코드 문자에서 해당 카테고리 모든 글자가 선택됩니다. 카테고리에 사용할 수 있는 내용은 지원되는 유니코드 일반 범주와 지원되는 명명된 블록을 참고하세요. 예시보기
\P{카테고리} 유니코드 문자에서 해당 카테고리를 제외한 모든 글자가 선택됩니다. 카테고리에 사용할 수 있는 내용은 지원되는 유니코드 일반 범주와 지원되는 명명된 블록을 참고하세요. 예시보기
\w 모든 글자, 10진수의 숫자, 밑줄 항목이 해당됩니다. 예시보기
\W 글자, 10진수의 숫자, 밑줄을 제외한 항목이 해당됩니다. 예시보기
\s 모든 공백 문자가 해당됩니다. 예시보기
\S 모든 공백 문자를 제외한 글자가 해당됩니다. 예시보기
\d 10진수 숫자가 해당됩니다. 예시보기
\D 10진수 숫자를 제외한 글자가 해당됩니다. 예시보기
문자 이스케이프
\r 캐리지 리턴이 해당됩니다. (Char 10, 타자기 앞으로 이동 명령) 예시보기
\n 줄바꿈이 해당됩니다. 예시보기
\t 탭이 해당됩니다.
[\b] 백스페이스가 해당됩니다. 이 뜻이 제대로 나타나려면 브라켓으로 둘러싸여야만 합니다.
\f 폼 피드가 해당됩니다.
\e 이스케이프가 해당됩니다.
\v 세로 탭이 해당됩니다.
\a 벨 문자가 해당됩니다.
\8진수 8진 문자로 글자 번호가 맞는 것을 찾습니다. 예시보기
\x16진수 두 자리의 16진(hex) 문자로 글자 번호가 맞는 것을 찾습니다. 예시보기
\u16진수 네 자리의 16진 표현 유니코드 문자로 맞는 것을 찾습니다. 예시보기
\c문자 문자로 지정된 ASCII 컨트롤 문자를 찾습니다.
앵커
^ 입력의 시작점을 찾습니다. 여러 줄은 줄마다 찾습니다. 예시보기
$ 입력의 끝점, 또는 여러 줄마다 \n 직전의 지점을 찾습니다. 예시보기
\A 입력의 시작점을 찾는다는 점에서 ^와 같지만, 여러 줄인 경우에 무관하게 제일 처음만 찾습니다. 예시보기
\Z 입력의 끝점이나 \n 직전을 찾는 점에서 $와 동일하지만, 여러 줄이어도 영향받지 않습니다. 예시보기
\z 어떠한 예외 없이 입력의 끝을 찾습니다. 빈 줄로 끝나면 빈 줄을 찾습니다. 예시보기
\G 이전에 찾은 지점을 다시 찾습니다. 지속적인 검색에 사용됩니다. 예시보기
\b 단어 경계로 찾습니다. 특히, \w와 \W 사이의 모든 구간을 찾습니다. 예시보기
\B 단어 경계가 아닌 곳을 찾습니다. 특히 \w와 \W 사이가 아닌 곳을 찾습니다. 예시보기
그룹화 구성
(하위패턴) 하위패턴을 찾고 이름 없는 그룹으로 만듭니다. 예시보기
(?<이름>하위패턴) 하위패턴을 찾고 이름으로 정의된 이름으로 그룹화합니다. 예시보기
(?<이전의 이름>하위패턴) 그룹 정의를 짝지을 수 있습니다. 괄호나 HTML 태그로 둘러싸인 구조를 찾을 수 있게 만듭니다. 이전에 정의된 그룹은 이전의 이름으로 지정됩니다. 하위패턴에 이름을 지정하여 기록할 수도 있고, 이름을 생략하여 무명의 그룹으로 만들 수 있습니다. 자세한 정보는 Morten Maate의 튜토리얼 둘러싸인 구조 찾기를 찾아보세요. 예시보기
(?:하위패턴) 기록하지 않는 그룹입니다. 그룹에 기록하지 않고 하위패턴을 괄호로 쌀 수 있게 해줍니다. 예시보기
(?enableddisabled:하위패턴) 하위패턴이 나머지 패턴과 다른 옵션을 갖도록 합니다. 내부 옵션 문자는 enabled 또는 disabled로 특정 옵션을 조정합니다. imnsx-imnsx로 나타납니다. (켜진 옵션-꺼진 옵션)

  • IgnoreCase: i, 대소문자 무관
  • Multiline: m, 여러줄. ^ $의 동작 변화
  • IgnorePatternWhitespace: n, 이스케이프 처리되지 않은 공백을 패턴에서 제거하고 #로 표시된 주석을 활성화합니다. 그러나 이 값은 개별 정규 표현식 언어 요소의 시작 부분을 나타내는 문자 클래스, 숫자 한정 기호 또는 토큰의 공백에 영향을주지 않거나 제거하지 않습니다.
  • Singleline: s, 단일줄. .이 \n을 포함하게 됨
  • ExplicitCapture: x,(?:패턴) 없이도 무명의 패턴 그룹을 기록하지 않음
예시보기
(?=하위패턴) 공백 없이 앞으로 검색합니다. 하위패턴이 우측으로 일치할 때 계속합니다. 예시보기
(?!하위패턴) 공백 없이 뒤로 검색합니다. 하위패턴이 왼쪽으로 일치할 때 계속합니다. 예시보기
(?<=하위패턴) Zero-width positive lookbehind assertion. Continues matching only if subpattern matches on the left. 예시보기
(?하위패턴) Zero-width negative lookbehind assertion. Continues matching only if subpattern does not match on the left. 예시보기
(?>하위패턴) Prevents backtracking over subpattern, which can improve performance.
수량
* 이전 요소가 0회 이상 나타난 경우 찾습니다. 예시보기
+ 이전 요소가 1회 이상 나타난 경우 찾습니다. 예시보기
? 이전 요소가 0회 또는 1회 나타난 경우 찾습니다. 예시보기
{n} 이전 요소가 정확히 n회 나타난 경우 찾습니다. 예시보기
{n,} 이전 요소가 최소 n회 이상 나타난 경우 찾습니다. 예시보기
{n,m} 이전 요소가 n회 이상 m회 이하 나타난 경우 찾습니다. 예시보기
*? 이전 요소가 0회 이상 나타난 것 중 패턴의 최소한의 경우만 찾습니다. 예시보기
+? 이전 요소가 1회 이상 나타난 것 중 패턴의 최소한의 경우만 찾습니다. 예시보기
?? 이전 요소가 0회 또는 1회 나타난 것 중 패턴의 최소한의 경우만 찾습니다. 예시보기
{n,}? 이전 요소가 최소 n회 이상 나타난 것 중 패턴의 최소한의 경우만 찾습니다. 예시보기
{n,m}? 이전 요소가 n회 이상 m회 이하 나타난 것 중 패턴의 최소한의 경우만 찾습니다. 예시보기
역(逆) 참조 구문
\숫자 이전에 숫자로 기록된 그룹을 찾습니다. 예시보기
\k<이름> 이전에 이름으로 지정된 그룹을 찾습니다. 예시보기
대체 구조
| ‘OR'(또는)의 논리 함수입니다. 이것으로 나뉘어진 모든 항목을 찾습니다. 예시보기
(?(하위패턴)yes|no) 하위패턴을 공백 없이 검사하여 다르게 처리합니다. 참인 경우, yes의 패턴으로 일치시키고, 거짓인 경우 no의 패턴으로 일치시킵니다. no 패턴은 선택 사항입니다. 예시보기
(?(그룹)yes|no) 성공적으로 찾은, 이전에 기록된 그룹인지 이름이나 숫자로 확인하여 다르게 처리합니다. 참인 경우 yes의 패턴으로 일치시키고, 아닌 경우 no의 패턴으로 시도합니다. no 패턴은 선택 사항입니다. 예시보기
치환
$number 숫자로 찾은 그룹 값을 나타냅니다.
${name} 이름으로 찾은 그룹 값을 나타냅니다.
$$ $ 문자를 나타냅니다.
$& 모든 일치한 결과를 나타냅니다.
$` 일치 영역 전까지의 모든 입력값을 나타냅니다.
$’ 일치한 값 뒤로 모든 입력값입니다.
$+ 기록된 마지막 그룹을 나타냅니다.
$_ 모든 입력값을 나타냅니다.
기타
(?enableddisabled) 패턴 중간에 옵션을 변경합니다. 자세한 값은 위 (?enabled-disabled:하위패턴)을 참조하세요.
(?# comment) 내용 속 주석이며, 패턴으로 처리되지 않습니다. 예시보기
# comment 주석 줄 끝으로, 패턴 처리되지 않습니다. 공백 무시 옵션이 켜있어야 사용할 수 있습니다. 예시보기

결론

어쩌다보니 본 블로그의 리다이렉트에 신나게 써먹고 있습니다.

멍청한 구글봇이 404로 망한 결과만 마구마구 양산하도록 만들지 않기 위해서 301 리다이렉트를 열심히 써줘야 하고, 그 일등 공신이 바로 정규식이거든요.

정규식 연습을 하고 싶으시면, RegExr에서 해보시는 게 좋을 것 같습니다.