REX: Look around
strsplit
strsplit
은 문자열을 주어진 문자(열)을 기준으로 분리한다.
다음의 덧셈을 구성하는 모든 숫자를 분리해내고자 한다면,
txt = '32+45+33+42+ 24 + 22 + 3'
strsplit(txt, ' *[+] *')
## [[1]] ## [1] "32" "45" "33" "42" "24" "22" "3"
단순히 +
를 없애는 것이 아니라 +
와 숫자 사이의 스페이스도 적절하게 없애줄 수 있다.
사라진 문자
사라진 글자가 그리울 수도 있다. 분리된 문자가 원본 그대로를 모두 보존하고 싶을 수도 있다.
하지만 strsplit
은 기준 문자(열)을 제거하고 문자열의 앞뒤부분만을 보존하는데 어쩌나? 방법은 기준 문자가 길이 0인 문자로 하는 것이다. 응? PCRE에는 Look Around가 있다!
txt = '32+45+33+42+ 24 + 22 + 3'
strsplit(txt, '(?<=[+])', perl=TRUE)
## [[1]] ## [1] "32+" "45+" "33+" "42+" " 24 +" " 22 +" " 3"
(?<= )
을 사용하면 앞쪽에 특수한 문자가 오길 기대한다. (?<=a)b
는 ab
의 b
를 나타내지만, cb
의 b
는 해당하지 않는다. (?<=a)
라고 쓰면? 어떤 곳이던 a
가 앞에 나타나는 지점을 의미한다. 예를 들어 bacd
의 a
와 c
사이, hamster
의 a
와 m
사이를 나타낸다. 따라서 strsplit
에 쓴다면, 분리할 지점은 있지만, 제거되는 문자는 없다.
분리될 지점을 상세화
Look around는 Look ahead와 Look behind가 있다. 이를 활용하면 분리될 지점을 좀 더 상세화할 수 있다. 예를 들어 앞에는 문자, 뒤에는 숫자가 나오는 지점에서 분리를 하고자 한다면,
txt = 'there are2 people over there. I saw3children'
strsplit(txt, '(?<=\\w)(?=\\d)', perl=TRUE)
## [[1]] ## [1] "there are" "2 people over there. I saw" "3children"
\w
는 알파벳과 숫자, 그리고 _
를 나타내고, \d
는 숫자를 의미한다.
txt = '거기2 명이 있었어. 아 오늘3시에 볼꺼지? 아 맞다 4시였지?'
strsplit(txt, '(?<=\\w)(?=\\d)', perl=TRUE)
## [[1]] ## [1] "거기2 명이 있었어. 아 오늘3시에 볼꺼지? 아 맞다 4시였지?"
UNICODE 정규표현식으로 \p{L}
은 문자를 나타낸다.
txt = '거기2 명이 있었어. 아 오늘3시에 볼꺼지? 아 맞다 4시였지?'
strsplit(txt, '(?<=\\p{L})(?=\\d)', perl=TRUE)
## [[1]] ## [1] "거기" "2 명이 있었어. 아 오늘" "3시에 볼꺼지? 아 맞다 4시였지?"
만약 빈 공간과 숫자가 연결되는 지점도 포함하고자 한다면,
txt = '거기2 명이 있었어. 아 오늘3시에 볼꺼지? 아 맞다 4시였지?'
strsplit(txt, '(?<=\\p{L}| )(?=\\d)', perl=TRUE)
## [[1]] ## [1] "거기" "2 명이 있었어. 아 오늘" "3시에 볼꺼지? 아 맞다 " "4시였지?"
결론
strplit
의 pattern
으로 (?<= )(?= )
을 쓰면 특정한 지점을 가리킬 수 있다. 이때 perl=TRUE
로 하는 것을 잊지 말자.
Leave a comment