regexp — 문자열에 정규식 매칭
regexp — 문자열에 정규식 매칭
어떤 문자열이 특정 패턴과 일치하는지 확인하고 싶을 때가 정말 많아요. regexp는 그런 정규식 매칭을 수행해 주는 명령이에요. 정규식 문법 자체에 대한 자세한 내용은 re_syntax 페이지를 따로 참고해야 하지만, 여기서는 regexp의 사용법과 각종 스위치를 집중적으로 다뤄요.
출처: 문서
본문
문법
regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?
동작 방식
regexp는 정규식 exp가 string의 일부 또는 전체와 일치하는지 판단해요. 일치하면 1, 일치하지 않으면 0을 반환하고, -inline이 지정된 경우는 예외예요(아래 참고).
string 이후에 추가 인자를 지정하면, string의 어느 부분이 exp와 일치했는지에 대한 정보를 반환할 변수 이름들로 취급돼요. matchVar는 exp 전체와 일치한 string의 범위로 설정되고, 첫 번째 subMatchVar는 exp 안의 가장 왼쪽 괄호로 묶인 부표현식과 일치한 문자들을 담고, 오른쪽으로 갈수록 다음 부표현식에 대응하는 변수들이 이어져요.
처음 인자가 -로 시작하면 스위치로 취급돼요. 지원되는 스위치는 다음과 같아요.
스위치
-about— 정규식 매칭을 시도하는 대신 정규식에 대한 정보를 담은 리스트를 반환해요. 리스트의 첫 요소는 부표현식 개수, 둘째 요소는 정규식의 여러 속성을 설명하는 속성 이름 리스트예요. 주로 디버깅 목적으로 사용돼요.-expanded— 공백과 주석이 무시되는 확장 정규식 문법을 사용하게 해요.(?x)임베디드 옵션을 지정하는 것과 같아요.-indices—matchVar와subMatchVar에 저장되는 내용을 바꿔요. 일치하는 문자를 저장하는 대신, 각 변수는 일치 범위의 첫 번째와 마지막 문자에 대한string안의 인덱스를 주는 두 개의 십진 문자열 리스트를 담아요.-line— 줄바꿈 민감 매칭을 활성화해요. 기본적으로 줄바꿈은 특별한 의미가 없는 완전히 평범한 문자예요. 이 플래그를 쓰면[^대괄호 표현식과.가 줄바꿈과 절대 일치하지 않고,^는 정상 기능에 더해 어떤 줄바꿈 뒤의 빈 문자열과도 일치하며,$는 정상 기능에 더해 어떤 줄바꿈 앞의 빈 문자열과도 일치해요.-linestop과-lineanchor를 둘 다 지정한 것, 또는(?n)임베디드 옵션과 같아요.-linestop—[^대괄호 표현식과.의 동작을 바꿔서 줄바꿈에서 멈추게 해요.(?p)옵션과 같아요.-lineanchor—^와$("앵커")의 동작을 바꿔 각각 줄의 시작과 끝과 일치하게 해요.(?w)옵션과 같아요.-nocase— 매칭 과정에서string의 대문자를 소문자로 취급하게 해요.-all— 정규식을 문자열에서 가능한 한 많이 일치시켜, 찾은 총 매치 수를 반환하게 해요. 매치 변수와 함께 지정하면 변수들은 마지막 매치에 대한 정보만 담아요.-inline— 명령이 매치 변수에 넣을 데이터를 대신 리스트로 반환하게 해요.-inline을 쓸 때는 매치 변수를 지정할 수 없어요.-all과 함께 쓰면 각 반복마다 리스트가 이어져 항상 평평한 리스트가 반환돼요. 매치 반복마다 전체 매치 데이터에 정규식의 각 부표현식마다 한 요소씩을 추가해서 반환해요. 예:regexp -inline -- {\w(\w)} " inlined " → in n regexp -all -inline -- {\w(\w)} " inlined " → in n li i ne e-start index— 정규식 매칭을 시작할 문자열 안의 문자 인덱스 오프셋을 지정해요. 이 인덱스 값은string index의 인덱스 인자와 같은 방식으로 해석돼요. 이 스위치를 쓸 때^는 줄의 시작과 일치하지 않고,\\A는 여전히index에서의 문자열 시작과 일치해요.-indices가 지정되면 인덱스는 입력 문자열의 절대 시작부터 세어요.index는 입력 문자열의 범위로 제한돼요.--— 스위치의 끝을 표시해요. 다음 인자는-로 시작하더라도exp로 취급돼요.
subMatchVar가 exp 안의 괄호 부표현식보다 많거나, 특정 부표현식이 문자열과 일치하지 않으면(예를 들어 일치하지 않은 표현식 부분에 있었기 때문에), 해당 subMatchVar는 -indices가 지정됐다면 "-1 -1"로, 그렇지 않으면 빈 문자열로 설정돼요.
예제
foobar의 실제 인스턴스가 아닌, foo로 시작하는 단어가 문자열에 처음 나타나는 위치를 찾고 그 뒤의 문자들을 단어 끝까지 변수로 가져오기:
regexp {\mfoo(?!bar\M)(\w*)} $string -> restOfWord
문자열 안에서 단어 badger(대소문자 무관)의 인덱스를 찾아 변수 location에 저장하기:
regexp -indices {(?i)\mbadger\M} $string location
이건 기본 문법인 고급 정규식 대신 기본 정규식으로도 쓸 수 있어요. 표현식 앞에 적절한 플래그를 붙이면 되죠:
regexp -indices {(?ib)\<badger\>} $string location
문자열 안의 8진수 자릿수 개수 세기:
regexp -all {[0-7]} $string
문자열 안의 모든 단어(비공백 문자의 모든 시퀀스)를 나열하기. split 명령보다 더 강력한 버전으로 유용해요:
regexp -all -inline {\S+} $string
더 알아보기
re_syntax: Tcl 정규식 문법 전체 참조regsub: 정규식 기반 치환string: 문자열 조작