정규표현식의 개념과 기초 문법

작성한지 10년이 지났는데도 notepad++ 관련한 키워드로 꾸준히 유입이 발생하고 있고,  그게 정규 표현식 관련한 글인데 별로 내용이 좋은 글이 아니다. (몇 가지 기초적인 문법만 요리책 식으로 나열해 놓은 거라…) 그래서 정규 표현식의 개념과 기초 문법 그리고 몇 가지 이 블로그에서 다루는 언어들에서 정규 표현식을 어떻게 쓰는지, 어떤 것들을 할 수 있는지 등에 대해서 알아볼 계획이다.

오늘은 그 첫 번째 순서로, 정규 표현식의 개념과 가장 기초가 되는 패턴 문법에 대해서 살펴보려고 한다.

정규표현식의 개념과 기초 문법 더보기

NSRegularExpression : 정규식 사용하기 – Swift

Swift의 정규식

Swift는 언어 자체에서 정규식을 지원하지 않고 FoundationNSRegularExpression 클래스를 이용한다.

  1. NSRegulareExpressioninitthrows이기 때문에 try와 같이 사용되어야 한다.
  2. 매치 결과는 TextCheckingResult 클래스의 인스턴스를 얻게 된다. 이는 매치영역 및 영역 내 각 매치 그룹의 범위를 NSRange값으로 가지고 있다.
  3. 문제는 Swift 문자열의 부분문자열은 Index<String.Index>에 의해서 얻을 수 있지, NSRange를 이용할 수 없다. 따라서 이를 컨버팅하는 편의함수나 타입 확장을 이용해야 한다. (사실 이 부분은 Linux 버전의 Swift의 문제이다. Apple Swift에서는 Foundation/Cocoa를 임포트하게 되면  NSString의 API가 그대로 String으로도 노출되기 때문에 그대로 사용이 가능하다.)

NSRegularExpression : 정규식 사용하기 – Swift 더보기

regex conditional

정규식의 조건절

조건절은 정규식에서는 흔히 쓰이는 표현은 아니다. 게다가 모든 정규식 엔진이 이를 지원하는 것도 아니다. 조건절을 사용해야 하는 경우라면 대부분의 경우 프로그래밍 로직으로 이를 보완하는1 형태로 많이 쓰이고 있고, 정규식 자체의 조건절이 꼭 필요한 케이스가 널리 알려져 있지 않기도 하다. regex conditional 더보기

정규식으로 짝수번째 숫자만 치환하기

코딩도장에서 흥미로운 문제를 하나 봤는데, 어떤 문자열에서 짝수번째로 등장한 숫자만 *로 치환하는 문제였다.문제의 출처가 정규식 관련 사이트인 것 같은데, 원본 주소는 링크가 깨진관계로…

예를 들자면

a1b2c3d4~e5f_6

과 같은 문자열이 있을 때 이중 숫자는 1, 2, 3, 4, 5, 6인데 그 중에서 짝수 번째로 등장하는 숫자만 *로 치환하는 것이다.

파이썬 구현은 매우 쉬운데….

def unvailEveryOtherDigits(str):
    s = []
    occ = 0
    for c in str:
        if c in "0123456789":
            c += 1
            if c % 2 == 0:
                s.append('*')
            else:
                s.append(c)
        else:
            s.append(c)
    return "".join(s)

이걸 정규식으로 풀어보자. 이걸 정규식으로는 못할 거라는 의견이 많은데, (숫자)(숫자가아닌것)(숫자) 이렇게 3개의 그룹을 매칭하고, 각 그룹 중 세번째 그룹만 *으로 치환하면 된다.

따라서

import re
print re.sub(r'(\d)(.*?)(\d)', '\\1\\2*', "a1b2c3d4e~f5g6")

뭐 이런식으로 간단히 풀 수 있다는 이야기.