본문 바로가기
R/Data Operation

R 문자열 처리 - stringr 패키지/정규표현식

by 통계열등생 2020. 12. 18.
반응형

R 문자열 처리 - base 패키지

small22.tistory.com/28

 

R 문자열 처리 - base 패키지

※ R 문자열 처리 - stringr 패키지/정규표현식 small22.tistory.com/29  ◎ Base Package 문자열 크기 nchar(x, type = "chars", allowNA = FALSE, keepNA = NA) <인수설명> type "bytes", "chars", "width" 3..

small22.tistory.com

 

 

 

 ◎ Stringr Package

 

str_extract 문자열의 위치(index) 출력
str_extract_all 문자열의 위치(index) 전체 출력
str_length 문자열 길이 출력
str_locate 문자열에서 특정 문자열 패턴의 첫번째 위치 찾기
str_locate_all 문자열에서 특정 문자열 패턴의 전체 위치 찾기
str_replace  문자열 교체
str_replace_all 문자열 전체 교체
str_sub 범위에 해당하는 부분 문자열 출력
str_split 기준문자를 중심으로 부분 문자열 리스트 출력

 

> install.packages("stringr")
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:

https://cran.rstudio.com/bin/windows/Rtools/
Installing package into ‘C:/Users/small22/Documents/R/win-library/4.0’
(as ‘lib’ is unspecified)
URL 'https://cran.rstudio.com/bin/windows/contrib/4.0/stringr_1.4.0.zip'을 시도합니다
Content type 'application/zip' length 215887 bytes (210 KB)
downloaded 210 KB

package ‘stringr’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\Public\Documents\ESTsoft\CreatorTemp\RtmpuEKJPl\downloaded_packages
> library(stringr)

먼저 stringr package를 설치해주고, 라이브러리에 올려준다.

stringr package 함수들은 대부분 문자열 패턴을 사용해야하는데 문자열 패턴은 정규표현식(Regular Expression)을 이용한다. 정규표현식의 설명은 글의 마지막에 표로 정리되어 있다.

 

 

 

  • str_extract / str_extract_all

1. 반복관련 메타문자

> string = 'hong35lee45kang55유관순25이사도시45'
> str_extract(string, "[a-z]{3}")
[1] "hon"
> str_extract_all(string, "[a-z]{3}") 
[[1]]
[1] "hon" "lee" "kan"

> str_extract_all(string, "[a-z]{3,}") 
[[1]]
[1] "hong" "lee"  "kang"

메타문자는 패턴을 지정할 때 쓰이는 특수기호로 이 글의 마지막에 표로 정리되어 있는 정규표현식에서 메타문자 기호가 설명되어있다.

str_extract() 함수는 패턴에 맞는 문자를 하나만 출력하지만 str_extract_all() 함수는 패턴에 맞는 문자를 모두 찾아서 출력해 준다.

[a-z]는 소문자이고 {3}은 3번 연속된 문자를 말한다. 해서 [a-z]{3}은 영어소문자가 연속으로 3번 나타나는 문자를 찾는 패턴이다. {3,}은 3번 이상 연속된 문자, {3,5}은 3번 ~ 5번 연속된 문자를 찾는 패턴이다.

 

> str_extract_all(string, "[가-힣]{3,5}") 
[[1]]
[1] "유관순"   "이사도시"

> name = str_extract_all(string, "[가-힣]{3,}") 
> unlist(name) 
[1] "유관순"   "이사도시"

한글 문자패턴을 찾을 때에는 [가-힣]을 사용한다.

str_extract() 와 str_extract_all() 함수의 출력값을 보면 리스트 자료형이다. 이를 unlist() 함수를 이용해 벡터 자료형으로 변환해 주었다.

 

> ages = str_extract_all(string, "[0-9]{2,}")
> ages = unlist(ages)  
> ages
[1] "35" "45" "55" "25" "45"
> num_ages = as.numeric(ages)
> num_ages
[1] 35 45 55 25 45
> cat('나이 평균 =', mean(num_ages))
나이 평균 = 41

 

 

2. 단어와 숫자관련 메타문자

> jumin = '홍길동 123456-1234567 24세 서울'
> str_extract_all(jumin, '[0-9]{6}-[1-4][0-9]{6}')
[[1]]
[1] "123456-1234567"

> str_extract_all(jumin, '\\d{6}-[1-4]\\d{6}')
[[1]]
[1] "123456-1234567"

여러 데이터가 섞인 문자열에서 주민번호를 찾는 패턴이다.

[0-9]는 0부터 9의 값이고 이는 역슬래시(\) 두번 + d 로 바꿔 쓸 수 있다.

주민번호 뒷자리 첫번째 숫자는 1부터 4의 값을 가지므로 [1-4]로 패턴을 지정해준다. [1-4]의 뒤에 { }가 붙지않으면 1부터 4까지의 숫자 중 1개의 숫자만 찾는다는 뜻이다.

 

> email = 'kp1234@naver.com'
> str_extract_all(email, '[a-z]{2,}[0-9]{3,}@[a-z]{3,}.[a-z]{2,}')
[[1]]
[1] "kp1234@naver.com"

> str_extract_all(email, '\\w{3,}@[a-z]{3,}.[a-z]{2,}')
[[1]]
[1] "kp1234@naver.com"

\\d 는 숫자만 찾는 패턴이지만 \\w는 영어,한글,숫자를 모두 찾는 패턴이다. [a-z]{2,}[0-9]{3,}같은 긴 패턴을 \\w{3,}로 짧게 표현할 수 있다.

 

 

3. 접두어(^) / 접미어($) 메타문자

> email2 = '1kp1234@naver.com' 
> str_extract_all(email2, '[a-z]\\w{3,}@[a-z]{3,}.[a-z]{2,}')
[[1]]
[1] "kp1234@naver.com"

> str_extract_all(email2, '^[a-z]\\w{3,}@[a-z]{3,}.[a-z]{2,}')
[[1]]
character(0)

> str_extract_all('kp1234@naver.com', '^[a-z]\\w{3,}@[a-z]{3,}.[a-z]{2,}')
[[1]]
[1] "kp1234@naver.com"

숫자가 먼저 나온 잘못된 이메일 형식의 문자열이다.

\\w는 숫자와 영어를 같이 인식함으로 앞에 [a-z]를 넣어줬고, 패턴의 맨앞에 접두어(^) 패턴을 지정하면 영어로 시작하는 문자열을 찾는다는 것이다. 잘못된 이메일 형식임으로 문자열을 찾지 못했고, 정상적인 이메일 형식은 잘 찾는 것을 알 수 있다.

 

> str_extract_all(email2, '[a-z]\\w{3,}@[a-z]{3,}.com$')
[[1]]
[1] "kp1234@naver.com"

> str_extract_all(email2, '^[a-z]\\w{3,}@[a-z]{3,}.com$')
[[1]]
character(0)

패턴의 맨뒤에 접미어($) 패턴을 지정하면 com으로 끝나는 문자열을 찾는다는 것이다.

접미어 패턴만 사용했을 때는 잘못된 이메일도 찾아졌지만 접두어 패턴와 같이 사용하면 잘못된 이메일은 찾지 않으면서 패턴을 간결하게 쓸 수 있다.

 

 

4. 특정문자 제외 메타문자

> string 
[1] "hong35lee45kang55유관순25이사도시45"
> result = str_extract_all(string, '[^0-9]{3,}') 
> result
[[1]]
[1] "hong"     "lee"      "kang"     "유관순"   "이사도시"

> name = str_extract_all(result[[1]], '[가-힣]{3,}')
> unlist(name)
[1] "유관순"   "이사도시"

꺽쇠(^)를 대괄호 안에 사용하면 이때는 접두어가 아니라 부정의 의미이다. [^0-9]는 숫자를 제외한 모든 문자열을 찾는 패턴이다.

 

 

 

  • str_length
> string
[1] "hong35lee45kang55유관순25이사도시45"
> length(string)
[1] 1
> str_length(string)
[1] 28
>
> unlist(name)
[1] "유관순"   "이사도시"
> str_length(unlist(name))
[1] 3 4

length() 함수는 벡터의 길이를 반환하고, str_length() 함수는 문자열의 길이를 반환한다. base package 함수 중 nchar() 함수와 비슷하다.

 

 

 

  • str_locate / str_locate_all
> string
[1] "hong35lee45kang55유관순25이사도시45"
> str_locate(string, 'g')
     start end
[1,]     4   4
> str_locate_all(string, 'g')
[[1]]
     start end
[1,]     4   4
[2,]    15  15

str_locate() 함수는 문자열에서 특정 문자열 패턴의 위치들 중 첫번째 위치를 찾는다. 위의 문자열에서 'g'는 4번 위치와 15번 위치에 있음을 알 수 있다.

 

 

 

  • str_replace / str_replace _all
> string
[1] "hong35lee45kang55유관순25이사도시45"
> str_replace(string, '[0-9]{2}', '')
[1] "honglee45kang55유관순25이사도시45"
> str_replace_all(string, '[0-9]{2}', '') 
[1] "hongleekang유관순이사도시"

문자열을 교체하는 함수이고, 문자열에서 숫자를 제거하는 코드이다.

 

> string2 = '($123,446)'
> num = str_replace_all(string2, '\\(|\\$|\\,|\\)', '')
> as.numeric(num)
[1] 123446

문자열에 포함된 특수문자를 제거할 때 사용할 수도 있다. 역슬래스(\) 두번 + 지우고 싶은 특수문자를 패턴으로 지정하면 된다.

 

 

 

  • str_sub
> string
[1] "hong35lee45kang55유관순25이사도시45"
> str_sub(string, 3, 5)
[1] "ng3"

str_sub() 함수는 범위에 해당하는 부분의 문자열을 출력해준다.

 

> str_locate_all(string, '[a-z]{1,}g')
[[1]]
     start end
[1,]     1   4
[2,]    12  15

> substr(string, c(1,12), c(4,15))
[1] "hong"
> str_sub(string, c(1,12), c(4,15))
[1] "hong" "kang"

위에서 설명한 str_locate_all() 함수를 사용해 'g'로 끝나는 이름들의 위치를 반환받고, str_sub() 함수를 사용해 해당 이름을 출력해보았다.

base package 함수 중에도 범위에 해당하는 부분의 문자열을 출력하는 subset() 함수가 있지만 str_sub() 함수처럼 여러개를 출력하지는 못한다.

 

 

 

  • str_split
> string3 = '홍길동,이순신,강감찬,유관순'
> str_split(string3, ',')
[[1]]
[1] "홍길동" "이순신" "강감찬" "유관순"

> strsplit(string3, split=',')
[[1]]
[1] "홍길동" "이순신" "강감찬" "유관순"

str_split() 함수는 기준문자를 중심으로 부분 문자열 리스트 출력한다. base package 함수 중 strsplit() 함수와 비슷하다.

 

 

 

 

 

 ◎ 정규 표현식

 

참고 사이트 : 위키백과 정규표현식

 

정규 표현식 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 노랑색 강조 부분은 다음 정규식을 사용했을 때 매치된 것이다. 정규 표현식(正規表現式, 영어: regular expression, 간단히 regexp[1] 또는 regex, rational expression)[2][3] 또

ko.wikipedia.org

 

메타문자 기능 설명
. 문자 1개의 문자와 일치한다. 단일행 모드에서는 새줄 문자를 제외한다.
[ ] 문자 클래스 "["과 "]" 사이의 문자 중 하나를 선택한다. "¦"를 여러 개 쓴 것과 같은 의미이다. 예를 들면 [abc]d는 ad, bd, cd를 뜻한다. 또한, "-" 기호와 함께 쓰면 범위를 지정할 수 있다. "[a-z]"는 a부터 z까지 중 하나, "[1-9]"는 1부터 9까지 중의 하나를 의미한다.
[^ ] 부정 문자 클래스 안의 문자를 제외한 나머지를 선택한다. 예를 들면 [^abc]d는 ad, bd, cd는 포함하지 않고 ed, fd 등을 포함한다. [^a-z]는 알파벳 소문자로 시작하지 않는 모든 문자를 의미한다.
^ 처음 문자열이나 행의 처음을 의미한다.
$ 문자열이나 행의 끝을 의미한다.
( ) 하위식 여러 식을 하나로 묶을 수 있다. "abc¦adc"와 "a(b¦d)c"는 같은 의미를 가진다.
\n 일치하는 n번째 패턴 일치하는 패턴들 중 n번째를 선택하며, 여기에서 n은 1에서 9 중 하나가 올 수 있다.
* 0회 이상 0개 이상의 문자를 포함한다. "a*b"는 "b", "ab", "aab", "aaab"를 포함한다.
{m, n} m회 이상 n회 이하 "a{1,3}b"는 "ab", "aab", "aaab"를 포함하지만, "b"나 "aaaab"는 포함하지 않는다.

 

 

 

 

 

<R 문자열 처리 - stringr 패키지/정규표현식>

반응형

댓글