[r] 문자가 문자열에 있는지 테스트

문자열이 다른 문자열의 하위 집합인지 확인하려고합니다. 예를 들면 다음과 같습니다.

chars <- "test"
value <- "es"

“value”가 “chars”문자열의 일부로 나타나면 TRUE를 반환하고 싶습니다. 다음 시나리오에서는 false를 반환하려고합니다.

chars <- "test"
value <- "et"



답변

grepl기능을 사용하십시오

grepl(value, chars, fixed = TRUE)
# TRUE

?grepl자세한 내용을 알아 보려면 사용하십시오 .


답변

대답

이 간단한 질문에 대한 답을 찾는 데 45 분이 걸렸습니다. 정답은:grepl(needle, haystack, fixed=TRUE)

# Correct
> grepl("1+2", "1+2", fixed=TRUE)
[1] TRUE
> grepl("1+2", "123+456", fixed=TRUE)
[1] FALSE

# Incorrect
> grepl("1+2", "1+2")
[1] FALSE
> grepl("1+2", "123+456")
[1] TRUE

해석

grep의 약어가 자체 인 리눅스 실행 파일의 이름을 따서 명명된다 ” G lobal R egular E xpression P RINT”는 입력 라인을 읽고 그들이 당신이 준 인수를 일치하는 경우 다음을 인쇄 할 것이다. “Global”은 입력 행의 어느 곳에서나 일치가 발생할 수 있음을 의미합니다. 아래 “Regular Expression”에 대해 설명하지만 문자열 (R은이 “문자”라고 함 class("abc")) 및 “Print “명령 줄 프로그램이기 때문에 출력을내는 것은 출력 문자열로 인쇄한다는 의미입니다.

이제 grep프로그램은 기본적으로 입력 라인에서 출력 라인에 이르는 필터입니다. 그리고 R의 grep함수도 마찬가지로 입력 배열을 취할 것으로 보입니다 . 나에게 전혀 알려지지 않은 이유 때문에 (약 1 시간 전에 R을 사용하기 시작한 것), 일치하는 목록이 아니라 일치하는 인덱스의 벡터를 반환합니다.

그러나 원래 질문으로 돌아가서, 우리가 정말로 원하는 것은 건초 더미에서 바늘을 찾았는지, 참 / 거짓 값인지 아는 것입니다. 그들은 분명히이 기능의 이름을하기로 결정했다 grepl“GREP”같이하지만, “와, L ogical”반환 값 (그들은, 예를 진실과 거짓 논리 값을 호출 class(TRUE)).

이제 우리는 그 이름이 어디에서 왔으며 무엇을해야하는지 알게되었습니다. 정규식으로 돌아갑니다. 인수는 문자열이지만 정규 표현식을 작성하는 데 사용됩니다 (이후 정규 표현식). 정규 표현식은 문자열을 일치시키는 방법입니다 (이 정의가 자극을 주면 그대로 두십시오). 예를 들어, 정규식 a은 문자와 일치하고 "a"정규식 a*은 문자와 "a"0 번 이상 a+일치하며 정규식 은 문자와 "a"1 번 이상 일치합니다 . 따라서 위의 예에서, 우리가 찾고있는 바늘 1+2은 정규 표현식으로 취급 될 때 “하나 이상 1 뒤에 2″가있는 것을 의미하지만 우리 뒤에는 플러스가 있습니다!

정규식으로 1 + 2

따라서 greplwithout 설정 을 사용 하지 않으면 fixed바늘이 실수로 건초 더미가되어 실수로 자주 작동하는 경우 OP의 예에서도 작동한다는 것을 알 수 있습니다. 그러나 그것은 잠복적인 버그입니다! 우리는 입력이 정규 표현식이 아닌 문자열이라는 것을 분명히해야 fixed합니다. 왜 고정 되었습니까? 실마리는 없습니다.이 답변을 북마크에 추가하십시오. 암기하기 전에 5 번 더 찾아봐야 할 것입니다.

몇 가지 마지막 생각

코드가 좋을수록 코드를 이해하기 위해 알아야 할 이력이 줄어 듭니다. 모든 인수는 적어도 두 가지 흥미로운 값을 가질 수 있습니다 (그렇지 않으면 인수가 될 필요는 없습니다). 문서는 9 개의 인수를 나열합니다.이를 호출하는 데 적어도 2 ^ 9 = 512 가지 방법이 있다는 것을 의미합니다. 쓰기, 테스트 및 기억 … 이러한 기능을 분리합니다 (분할, 서로 의존성 제거, 문자열 사물이 정규식 사물과 벡터 사물과 다름) 옵션 중 일부는 상호 배타적이며, 코드를 사용하는 잘못된 방법을 사용자에게 제공하지 않습니다. 즉, 문제가있는 호출은 논리적으로 무의미하지 않고 (존재하지 않는 옵션을 전달하는 등) 구조적으로 무의미해야합니다. 설명하기 위해 경고를 보냅니다). 은유 적으로 넣어 : 10 층 측면의 전면 도어를 벽으로 교체하는 것은 사용에 대해 경고하는 표지판을 걸는 것보다 낫지 만 둘 중 하나보다 낫습니다. 인터페이스에서 함수는 호출자가 아닌 인수의 모양을 정의합니다 (호출자는 함수에 의존하기 때문에 모든 사람이 호출하고자하는 모든 것을 유추하여 함수도 호출자에 따라 달라집니다. 주기적 종속성은 시스템을 빠르게 방해하고 기대하는 이점을 제공하지 않습니다). 혼란스러운 유형에 매우주의하십시오. 그것은 디자인 결함입니다. 모든 사람이 호출하고자하는 모든 것을 유추하면 함수도 호출자에게 의존하게 되며이 유형의 주기적 종속성은 시스템을 빠르게 방해하고 기대하는 이점을 제공하지 않습니다). 혼란스러운 유형에 매우주의하십시오. 그것은 디자인 결함입니다. 모든 사람이 호출하고자하는 모든 것을 유추하면 함수도 호출자에게 의존하게 되며이 유형의 주기적 종속성은 시스템을 빠르게 방해하고 기대하는 이점을 제공하지 않습니다). 혼란스러운 유형에 매우주의하십시오. 그것은 디자인 결함입니다.TRUE0"abc"모든 벡터이다.


답변

당신이 원하는 grepl:

> chars <- "test"
> value <- "es"
> grepl(value, chars)
[1] TRUE
> chars <- "test"
> value <- "et"
> grepl(value, chars)
[1] FALSE


답변

stringi패키지 에서이 기능을 사용하십시오 .

> stri_detect_fixed("test",c("et","es"))
[1] FALSE  TRUE

일부 벤치 마크 :

library(stringi)
set.seed(123L)
value <- stri_rand_strings(10000, ceiling(runif(10000, 1, 100))) # 10000 random ASCII strings
head(value)

chars <- "es"
library(microbenchmark)
microbenchmark(
   grepl(chars, value),
   grepl(chars, value, fixed=TRUE),
   grepl(chars, value, perl=TRUE),
   stri_detect_fixed(value, chars),
   stri_detect_regex(value, chars)
)
## Unit: milliseconds
##                               expr       min        lq    median        uq       max neval
##                grepl(chars, value) 13.682876 13.943184 14.057991 14.295423 15.443530   100
##  grepl(chars, value, fixed = TRUE)  5.071617  5.110779  5.281498  5.523421 45.243791   100
##   grepl(chars, value, perl = TRUE)  1.835558  1.873280  1.956974  2.259203  3.506741   100
##    stri_detect_fixed(value, chars)  1.191403  1.233287  1.309720  1.510677  2.821284   100
##    stri_detect_regex(value, chars)  6.043537  6.154198  6.273506  6.447714  7.884380   100


답변

또한 “stringr”라이브러리를 사용하여 수행 할 수 있습니다 .

> library(stringr)
> chars <- "test"
> value <- "es"
> str_detect(chars, value)
[1] TRUE

### For multiple value case:
> value <- c("es", "l", "est", "a", "test")
> str_detect(chars, value)
[1]  TRUE FALSE  TRUE FALSE  TRUE


답변

문자열 (또는 문자열 집합)에 여러 개의 하위 문자열이 포함되어 있는지 확인하려는 경우에도 ‘|’ 두 개의 하위 문자열 사이

>substring="as|at"
>string_vector=c("ass","ear","eye","heat")
>grepl(substring,string_vector)

당신은 얻을 것이다

[1]  TRUE FALSE FALSE  TRUE

첫 번째 단어에는 하위 문자열 “as”가 있고 마지막 단어에는 하위 문자열 “at”가 포함되므로


답변

사용 grep또는 grepl 그러나 당신이 정규 표현식을 사용할지 여부를 인식 .

기본적으로 grep관련 은 리터럴 하위 문자열이 아닌 일치 하는 정규식을 사용합니다 . 그것을 기대하지 않고 유효하지 않은 정규식과 일치하려고하면 작동하지 않습니다.

> grep("[", "abc[")
Error in grep("[", "abc[") :
  invalid regular expression '[', reason 'Missing ']''

실제 부분 문자열 테스트를 수행하려면을 사용하십시오 fixed = TRUE.

> grep("[", "abc[", fixed = TRUE)
[1] 1

정규식을 원한다면 훌륭하지만 OP가 묻는 것처럼 보이지는 않습니다.