Ayden's journal

정규표현식(RegEx)

단어 집합 [ ]

집합 내에 해당하는 단어가 포함되어있으면 선택된다. 가령 [bcd]ash 라고 검색하면 bash, cash, dash가 모두 선택되는 식이다. 혹은 하이픈(-)을 사용하여 이를 더 간단하게 적어줄 수 있는데, 동일한 예시에서라면 [b-d]ash로 사용할 수 있다. 보다 긴 예시에서라면 소문자 a에서부터 소문자 z까지의 단어 집합을 [a-z]로 표현하게 된다.

  • 숫자 집합 : [0-9]
  • 소문자 집합 : [a-z]
  • 대문자 집합 : [A-Z]
  • 한글 집합 : [가-힣]

만약 숫자 집합과 대문자 집합을 한 번에 표기하려고 [0-Z]로 쓰게 되면 생각지 못했던 특수 문자들이 함께 검색되는 것을 확인할 수 있다. 이는 하이픈이 아스키코드를 사용해 문자 집합을 표현하기 때문이다. [0-Z]라는 표현식은 아스키코드 48번부터 90번까지를 의미하게 되므로, 자연히 그 사이의 콜론이나 물음표 같은 특수문자도 포함하게 된다. 이러한 특수문자의 포함 없이 표기하기 위해서는 [0-9A-Z]와 같은 방법으로 표현해주면 된다. [A-Z0-9]도 동일하게 작동한다.

 

메타 문자

특정 문자를 제외하고 검색하기 위해서는 캐럿(^)을 사용해야 하는데, 이 캐럿 자체가 원고를 교정하면서 '제외할 단어'를 표시할 때 사용하므로(당근을 뜻하는 carrot이나 보석 무게를 잴 때의 carat이 아니라 caret이다), 정규표현식에서도 역시 특정한 문자를 제외한다는 표현으로 쓰이고 있다. [^0-9]라고 쓰게 되면 이것은 숫자를 제외한 그 외 모든 문자를 선택하겠다는 표현이 된다.

만약 특정 단어 앞뒤에 어떤 단어가 올지 모른다면 모든 문자를 의미하는 닷(.)을 사용할 수 있다. 만약 .ash를 검색하면 bash, cash, dash는 물론이고 rash나 wash, mash 같은 단어나 5ash 같이 숫자가 포함된 경우도 검색되며, 심지어는 앞에 공백이 있는 volcanic ash의 ' ash'도 검색될 것이다. 

이처럼 닷과 캐럿 뿐만 아니라 하이픈이나 단어 집합을 표현하는 대괄호 역시 정규표현식에서는 일반적인 용례와 다르게 사용되는데, 이를 '메타 문자'라고 부른다. 만약 문자열 속에서 마침표로 쓰인 .을 찾고 싶다면, 반드시 역슬래시를 사용해 \.의 형태로 검색해야 한다. 다른 메타 문자 역시 역슬래시를 사용하여 일반 문자로 사용된 경우를 검색할 수 있다. 백슬래시 자체도 메타 문자기 때문에 백슬래시를 검색하려면 \\의 형태로 검색하게 된다.

 

공백 문자

흔히 [ \t\n\r\f\v]로 쓰이는데, 처음에 backspace가 있다는 사실을 유념해야 한다. 그 외의 역슬래시들은 다음을 의미한다.

  • \t : 수평 탭
  • \n : 줄바꿈
  • \r : 복귀(캐리지 리턴)
  • \f : 페이지 나누기(폼 피드): 프린트 전용
  • \v : 수직 탭: 프린트 전용

 

문자 클래스

자주 쓰이는 집합 표현을 축약된 형태로 간단하게 사용할 수 있도록 해준다. 문자 클래스에는 아래의 여섯 가지가 존재한다.

    문자 집합 문자 클래스
숫자 합집합 [0-9] \d
여집합 [^0-9] \D
영어 대소문자 + 숫자 + _(언더바) 합집합 [a-zA-Z0-9_] \w
여집합 [^a-zA-Z0-9_] \W
공백 문자 합집합 [ \t\n\r\f\v] \s
여집합 [^ \t\n\r\f\v] \S

소문자로 사용된 문자 클래스의 여집합은 대문자로 사용된 문자 클래스이다. 이 점을 기억한다면 합집합으로서의 문자 클래스만 기억해도 여집합의 문자 클래스를 기억해낼 수 있을 것이다.

 

수량자 {n}

한국에서 사용되는 휴대전화번호는 010-****-**** 의 형식으로 되어있다. 이러한 일반적인 형태의 번호를 모두 검색하고 싶다면 문자 클래스를 사용하여 010-\d\d\d\d-\d\d\d\d로 찾아볼 수 있겠다. 그런데 수량자를 사용하면 같은 문자 클래스를 여러번 사용하지 않고도 검색이 가능하다. 숫자가 네 번 반복되므로 010-\d{4}-\d{4}로 표현할 수 있다.

그런데 해외의 전화번호는 숫자의 자리가 들쭉날쭉하다. 이런 경우 최소값과 최대값을 부여하여 {최소값, 최대값}의 형태로 검색할 수 있다. 만약 최대값을 빈칸으로 두면 최소값 이상으로 반복되는 모든 숫자를 찾아낸다. 번호가 3개 미만일 경우 근본이 없는 번호로 취급해 제외한다면, 표현식은 아마 010-\d{3,}-\d{3,} 와 같은 형태가 될 것이다.

 

수량자의 메타 문자

일반적으로 수량자에 쓰이는 메타 문자로는 ? * + 가 있다.

?는 직전 문자가 존재하지 않거나, 존재하는 경우에만 일치한다. 가령 'https?'로 검색할 경우 http와 https 둘 다 반환될 것이다. 'c?ash'의형태라면 cash와 ash는 물론이고 문자열 bash 속의 ash까지도 모두 찾아낼 것이다.

*와 +는 제한 없이 모든 숫자를 나타낸다. 그런데 *는 앞에 문자가 하나도 없어도 선택되는 반면, +는 앞에 최소 1개의 문자가 반드시 필요하다. 만약 \w*ash로 검색한다면 ash와 cash, bash는 물론 crash, splash까지도 검색될 것이다. 그러나 \w+ash로 검색하면 ash는 검색되지 않는 것이다.

 

탐욕적 수량자와 게으른 수량자

앞서 살펴본 {min,} * + 는 텍스트의 앞부터 탐색하는 것이 아니라, 마지막부터 한꺼번에 전부 찾아내므로 최대한 큰 덩어리의 문자열을 과도하게 일치시키게 된다. 이러한 수량자의 특성을 '탐욕적(greedy)'이라 부른다. 이렇게 과도하게 일치되는 것을 방지하고 원하는 부분만 정확하게 일치시키기 위해 수량자의 성질을 '게으르게(lazy)' 변경하는 것이 좋은데, 이는 ? 수량자를 사용한다.

  • * ➠ *?
  • + ➠ +?
  • {min,} ➠ {min,}?

 

문자의 경계 \b \B

이 문자 클래스들은 문자를 찾는 것이 아니라, 문자와 공백의 연속에서 나타나는 특정한 '위치'를 찾아낸다. \b는 문자와 문자가 아닌 곳의 경계를 나타내며, /B는 문자와 문자의 경계를 나타낸다. 가령 "this is the sunrise" 라는 문장에서 this의 is만을 찾고 싶다면, \Bis\b를 통해 this에 있는 is만 골라낼 수 있다. be동사로사의 is를 검색하고 싶다면 \bis\b 혹은 sunrise의 is만 검색하고 싶다면 \Bis\B로 검색하면 된다.

만약 문장의 경계를 나누고 싶다면 ^와 $ 사이에 찾고자 하는 문장을 입력하면 된다.

 

하위 표현식(Subexpression)

이것은 특정 패턴, 표현식을 하나의 항목으로 처리하는 방식이다. 하위 표현식을 사용하려면 소괄호를 사용해야 한다. 위의 수량자 항목에서 살펴본 전화번호를 찾는 표현식 010-\d{4}-\d{4}를 하위 표현식으로 적는다면 010(-\d{4}){2}로 표현할 수 있다.

하위 표현식을 사용하면 or 연산자를 통해 여러 값 가운데 한 가지를 선택할 수도 있다. 가령 전화번호의 경우 010 뿐만 아니라 011도 있고, 018도 있는데, 이러한 세 가지 경우를 or 연산자 통해 (010|011|018)(-\d{4}){2}와 같은 형태로 표현하게 된다.

 

전방/후방 탐색

문자열을 찾기 위한 패턴의 일부가 되지만, 해당 정규 표현식으로 찾아지는 문자열 결과에는 반영되지 않도록 하는 문법이다. 전방탐색은 해당 조건 뒤쪽의 부분을 생략하며 (?= )의 형태로 사용되고, 반대로 후방탐색은 해당 조건의 앞 부분을 생략하며 (?<= )로 나타낸다.

만약 전화번호의 가운데 부분만 골라서 찾아내려면 (?<=010-)(\d{4})(?=-\d{4})와 같은 형태로 사용이 가능하다.

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기