R-Studio 정규식의 사용 Part.1

R-Studio의 강력한 정규식을 이용한 데이터제어

Featured image

R-Studio 의 정규식

데이터의 필터를 위한 강력한 정규식 표현

Use Descriptions
\\d 숫자
\\D 숫자가 아닌 것
\\s 공백
\\S 공백이 아닌 것
\\w 단어
\\W 단어가 아닌 것
\\t Tab
\\n New Line (엔터 문자)
^ 시작되는 글자
$ 마지막 글자
\ Escape Character (탈출 문자)
| 두 개 이상의 조건 (OR)
[a-z] 영어 소문자
[A-z] 모든 영문자
i+ i가 최소 1회는 나오는 경우
i* i가 최소 0회 이상 나오는 경우
i? i가 최소 0회에서 최대 1회만 나오는 경우
(optional)
i{n} i가 연속적으로 n회 나오는 경우
i{n1,n2} i가 n1에서 n2회 나오는 경우
i{n,} i가 n회 이상 나오는 경우
’ , ‘ 뒤의 공백 유의
[:alnum:] 문자와 숫자가 나오는 경우 : [:alpha:] and [:digit:]
[:alpha:] 문자가 나오는 경우 : [:lower:] and [:upper:]
[:blank:] 공백이 있는 경우
[:cntrl:] 제어문자가 있는 경우
[:digit:] 0 ~ 9
[:graph:] Graphical characters : [:alnum:] and [:punct:]
[:lower:] 소문자가 있는 경우
[:print:] 숫자, 문자, 특수문자, 공백 모두
[:space:] 공백문자
[:upper:] 대문자가 있는 경우
[:xdigit:] 16진수가 있는 경우

함수 예제

# # 정규표현식
# install.packages("stringr")
library(stringr)

#str_extract(str, '[0-9]{2}') : 연속된 숫자로 되어있는 문자 가져오세요.(예:13, 15 같은 10의자리수)
str <- "홍길동15강감찬25을지문덕35"
test01 <- str_extract(str, '[0-9]{2}')
test01

#all이 붙으면 연속된 10의자리수 다뽑아옴 str에선 15, 25, 35 가 뽑아와짐.
test02 <- str_extract_all(str, '[0-9]{2}')
test02

str(test01)
str(test02)
unlist(test02)

string <- "hong1234김유신5678"
string

# 그냥 length 는 컬럼수 리턴시킴
str(string)
length(string)
len <- str_length(string) # str_length(str)은 문자열의 길이를 리턴해줌줌
len

string2 <- c("hello", "math") # 컬럼2개 리턴 시켜줌
length(string2)
len2 <- str_length(string2) # str_length(str)은 문자열의 길이를 리턴해줌줌
len2

# 찾는 단어의 인덱스 번호를 str과 end로 출력해줌.
# 찾고자 하는 단어가 없으면 NA/NA 가 출력됨.
string <- "hong1234김유신5678"
findWord <- "김유신"
loc <- str_locate(string, findWord)
loc

# 문자열 자르기
# str_sub(string, 1, 9-1)
# str_sub([string[]], int str, int end) : str ~ end 까지 추출
string_sub <- str_sub(string, 1, 9-1)
string_sub

# loc의 값을 이용하여 자르기
useLoc<- str_sub(string, 1, loc[1]-1)
useLoc

# 대소문자 변환
string3 <- "hong1234"

upper <- str_to_upper(string3)
upper

lower <- str_to_lower(string3)
lower

# 치환 함수
string3 <- "hong1234"
string_rep <- str_replace(string3, "hong", "kang")
string_rep

string_rep2 <- str_replace(string3, "1234", "5678")
string_rep2

string4 <- "hong1234hong5678"
string4

replace3 <- str_replace(string4, "hong", "kim")
replace3

replace4 <- str_replace_all(string4, "hong", "kim")
replace4

replace4 <- str_replace_all(string4, "[0-9]", "")
replace4

string5 <- "aaa123"
string6 <- "bbb456"

# str_c(str1, str2)문자열 결합
concat1 <- str_c(string5, string6)
concat1

string7 <- "aaa,bbb,ccc"
split1 <- str_split(string7, ',')
split1
vec <- unlist(split1)
vec

# 복사, 붙혀넣기
members <- c("홍길동10", "김유신20", "이순신30")
members

# members 의 문자 구분자를 , 로 바꿔버림
string_joun <- paste(members, collapse = ',')
string_joun

paste("안녕", "여러분", sep='/')

# 벡터 사용시에는 collapse 를 사용 해야함.
data <- c("안녕", "여러분")
paste(data, collapse = '/')

# 정규식
myStr <- "홍길동&10&역삼동&hong@naver.com=박영희&20&공덕동&park@daum.net"
delimiter <- '='

# 문자열 자르기 delimiter 를 기준으로 문자열을 자르고 simplify 옵션을 통해 벡터로 변환
mySplit <- str_split(myStr, delimiter, simplify = T)
mySplit

# 벡터 문자열 을 출력하기
for (str in mySplit) {
  # print(str)
  delimiter <- '&'
  mydata <- str_split(str, delimiter, simplify = T)
  print(mydata[1])
  print("=============")
}

# 메일도 따로 분리 하기.
vec <- c()
for (str in mySplit) {
  # print(str)
  delimiter <- '&'
  mydata <- str_split(str, delimiter, simplify = T)
  
  delimiter <- '@'
  idEmail <- str_split(mydata[4], delimiter, simplify = T)
  vec <- c(vec, c(mydata[1], mydata[2], mydata[3], idEmail[1], idEmail[2]))
}
vec

# 2행 으로 만들고 나머지 열로 분리
mat <- matrix(vec, nrow = 2, byrow = T)
mat

# 데이터 프레임 만들고 열 이름 대입
df <- as.data.frame(mat)
colnames(df) <- c("이름", "나이", "주소", "아이디", "메일")
str(df)

# 데이터 프레임 나이 컬럼의 자료형을 바꿔버림
a <- df$나이[1]
a <- as.character(a)
as.numeric(a)

# str 나누기s
myStr <- "사과10=배20=감15=사과30"
mydata <- str_split(myStr, '=', simplify = T)
mydata

vec <- c()
for(i in mydata) {
  name <- str_extract(i, "[가-히]{1,}")
  qty <- str_extract(i, "[0-9]{2}")
  str(name)
  vec <- c(vec, name, qty)
}

vec
mat <- matrix(vec, ncol=2, byrow = T)
dffruit <- as.data.frame(mat)
colnames(dffruit) <- c("과일", "수량")
dffruit

# test 문제
string <- "kim100김유신/lee200이순신"

#아이디와 나이와 이름으로 분리
user <- str_split(string, '/', simplify = T)
user

#나이에 +50을 연산하세요.
#알파벳은 모두 대문자로 변경하세요.

vec <- c()
for(i in user) {
  nameLast <- str_extract(i, "[a-z]{3}")
  age <- str_extract(i, "[0-9]{3}")
  name <- str_extract(i, "[가-하]{1,}")
  vec <- c(vec, str_to_upper(nameLast), as.numeric(age)+50, name)
}
vec

#2행 3열의 dataframe을 만들어 보세요.
mat <- matrix(vec, ncol=3, byrow = T) # 프레임 만들기전에 행렬 변환(2행) (행기준 나열)
dffruit <- as.data.frame(mat) # 데이타 프레임
dffruit
colnames(dffruit) <- c("성", "나이", "이름")
dffruit

콘솔 결과

> # # 정규표현식
> # install.packages("stringr")
> library(stringr)
> 
> #str_extract(str, '[0-9]{2}') : 연속된 숫자로 되어있는 문자 가져오세요.(예:13, 15 같은 10의자리수)
> str <- "홍길동15강감찬25을지문덕35"
> test01 <- str_extract(str, '[0-9]{2}')
> test01
[1] "15"
> 
> #all이 붙으면 연속된 10의자리수 다뽑아옴 str에선 15, 25, 35 가 뽑아와짐.
> test02 <- str_extract_all(str, '[0-9]{2}')
> test02
[[1]]
[1] "15" "25" "35"

> 
> str(test01)
 chr "15"
> str(test02)
List of 1
 $ : chr [1:3] "15" "25" "35"
> unlist(test02)
[1] "15" "25" "35"
> 
> string <- "hong1234김유신5678"
> string
[1] "hong1234김유신5678"
> 
> # 그냥 length 는 컬럼수 리턴시킴
> str(string)
 chr "hong1234김유신5678"
> length(string)
[1] 1
> len <- str_length(string) # str_length(str)은 문자열의 길이를 리턴해줌줌
> len
[1] 15
> 
> string2 <- c("hello", "math") # 컬럼2개 리턴 시켜줌
> length(string2)
[1] 2
> len2 <- str_length(string2) # str_length(str)은 문자열의 길이를 리턴해줌줌
> len2
[1] 5 4
> 
> # 찾는 단어의 인덱스 번호를 str과 end로 출력해줌.
> # 찾고자 하는 단어가 없으면 NA/NA 가 출력됨.
> string <- "hong1234김유신5678"
> findWord <- "김유신"
> loc <- str_locate(string, findWord)
> loc
     start end
[1,]     9  11
> 
> # 문자열 자르기
> # str_sub(string, 1, 9-1)
> # str_sub([string[]], int str, int end) : str ~ end 까지 추출
> string_sub <- str_sub(string, 1, 9-1)
> string_sub
[1] "hong1234"
> 
> # loc의 값을 이용하여 자르기
> useLoc<- str_sub(string, 1, loc[1]-1)
> useLoc
[1] "hong1234"
> 
> # 대소문자 변환
> string3 <- "hong1234"
> 
> upper <- str_to_upper(string3)
> upper
[1] "HONG1234"
> 
> lower <- str_to_lower(string3)
> lower
[1] "hong1234"
> 
> # 치환 함수
> string3 <- "hong1234"
> string_rep <- str_replace(string3, "hong", "kang")
> string_rep
[1] "kang1234"
> 
> string_rep2 <- str_replace(string3, "1234", "5678")
> string_rep2
[1] "hong5678"
> 
> string4 <- "hong1234hong5678"
> string4
[1] "hong1234hong5678"
> 
> replace3 <- str_replace(string4, "hong", "kim")
> replace3
[1] "kim1234hong5678"
> 
> replace4 <- str_replace_all(string4, "hong", "kim")
> replace4
[1] "kim1234kim5678"
> 
> replace4 <- str_replace_all(string4, "[0-9]", "")
> replace4
[1] "honghong"
> 
> string5 <- "aaa123"
> string6 <- "bbb456"
> 
> # str_c(str1, str2)문자열 결합
> concat1 <- str_c(string5, string6)
> concat1
[1] "aaa123bbb456"
> 
> string7 <- "aaa,bbb,ccc"
> split1 <- str_split(string7, ',')
> split1
[[1]]
[1] "aaa" "bbb" "ccc"

> vec <- unlist(split1)
> vec
[1] "aaa" "bbb" "ccc"
> 
> # 복사, 붙혀넣기
> members <- c("홍길동10", "김유신20", "이순신30")
> members
[1] "홍길동10" "김유신20" "이순신30"
> 
> # members 의 문자 구분자를 , 로 바꿔버림
> string_joun <- paste(members, collapse = ',')
> string_joun
[1] "홍길동10,김유신20,이순신30"
> 
> paste("안녕", "여러분", sep='/')
[1] "안녕/여러분"
> 
> # 벡터 사용시에는 collapse 를 사용 해야함.
> data <- c("안녕", "여러분")
> paste(data, collapse = '/')
[1] "안녕/여러분"
> 
> # 정규식
> myStr <- "홍길동&10&역삼동&hong@naver.com=박영희&20&공덕동&park@daum.net"
> delimiter <- '='
> 
> # 문자열 자르기 delimiter 를 기준으로 문자열을 자르고 simplify 옵션을 통해 벡터로 변환
> mySplit <- str_split(myStr, delimiter, simplify = T)
> mySplit
     [,1]                              [,2]                            
[1,] "홍길동&10&역삼동&hong@naver.com" "박영희&20&공덕동&park@daum.net"
> 
> # 벡터 문자열 을 출력하기
> for (str in mySplit) {
+   # print(str)
+   delimiter <- '&'
+   mydata <- str_split(str, delimiter, simplify = T)
+   print(mydata[1])
+   print("=============")
+ }
[1] "홍길동"
[1] "============="
[1] "박영희"
[1] "============="
> 
> # 메일도 따로 분리 하기.
> vec <- c()
> for (str in mySplit) {
+   # print(str)
+   delimiter <- '&'
+   mydata <- str_split(str, delimiter, simplify = T)
+   
+   delimiter <- '@'
+   idEmail <- str_split(mydata[4], delimiter, simplify = T)
+   vec <- c(vec, c(mydata[1], mydata[2], mydata[3], idEmail[1], idEmail[2]))
+ }
> vec
 [1] "홍길동"    "10"        "역삼동"    "hong"      "naver.com" "박영희"    "20"        "공덕동"   
 [9] "park"      "daum.net" 
> 
> # 2행 으로 만들고 나머지 열로 분리
> mat <- matrix(vec, nrow = 2, byrow = T)
> mat
     [,1]     [,2] [,3]     [,4]   [,5]       
[1,] "홍길동" "10" "역삼동" "hong" "naver.com"
[2,] "박영희" "20" "공덕동" "park" "daum.net" 
> 
> # 데이터 프레임 만들고 열 이름 대입
> df <- as.data.frame(mat)
> colnames(df) <- c("이름", "나이", "주소", "아이디", "메일")
> str(df)
'data.frame':	2 obs. of  5 variables:
 $ 이름  : Factor w/ 2 levels "박영희","홍길동": 2 1
 $ 나이  : Factor w/ 2 levels "10","20": 1 2
 $ 주소  : Factor w/ 2 levels "공덕동","역삼동": 2 1
 $ 아이디: Factor w/ 2 levels "hong","park": 1 2
 $ 메일  : Factor w/ 2 levels "daum.net","naver.com": 2 1
> 
> # 데이터 프레임 나이 컬럼의 자료형을 바꿔버림
> a <- df$나이[1]
> a <- as.character(a)
> as.numeric(a)
[1] 10
> 
> # str 나누기s
> myStr <- "사과10=배20=감15=사과30"
> mydata <- str_split(myStr, '=', simplify = T)
> mydata
     [,1]     [,2]   [,3]   [,4]    
[1,] "사과10" "배20" "감15" "사과30"
> 
> vec <- c()
> for(i in mydata) {
+   name <- str_extract(i, "[가-히]{1,}")
+   qty <- str_extract(i, "[0-9]{2}")
+   str(name)
+   vec <- c(vec, name, qty)
+ }
 chr "사과"
 chr "배"
 chr "감"
 chr "사과"
> 
> vec
[1] "사과" "10"   "배"   "20"   "감"   "15"   "사과" "30"  
> mat <- matrix(vec, ncol=2, byrow = T)
> dffruit <- as.data.frame(mat)
> colnames(dffruit) <- c("과일", "수량")
> dffruit
  과일 수량
1 사과   10
2      20
3      15
4 사과   30
> 
> # test 문제
> string <- "kim100김유신/lee200이순신"
> 
> #아이디와 나이와 이름으로 분리
> user <- str_split(string, '/', simplify = T)
> user
     [,1]           [,2]          
[1,] "kim100김유신" "lee200이순신"
> 
> #나이에 +50을 연산하세요.
> #알파벳은 모두 대문자로 변경하세요.
> 
> vec <- c()
> for(i in user) {
+   nameLast <- str_extract(i, "[a-z]{3}")
+   age <- str_extract(i, "[0-9]{3}")
+   name <- str_extract(i, "[가-하]{1,}")
+   vec <- c(vec, str_to_upper(nameLast), as.numeric(age)+50, name)
+ }
> vec
[1] "KIM"    "150"    "김유신" "LEE"    "250"    "이순신"
> 
> #2행 3열의 dataframe을 만들어 보세요.
> mat <- matrix(vec, ncol=3, byrow = T) # 프레임 만들기전에 행렬 변환(2행) (행기준 나열)
> dffruit <- as.data.frame(mat) # 데이타 프레임
> dffruit
   V1  V2     V3
1 KIM 150 김유신
2 LEE 250 이순신
> colnames(dffruit) <- c("성", "나이", "이름")
> dffruit
    나이   이름
1 KIM  150 김유신
2 LEE  250 이순신