我正在尝试确定字符串是否是另一个字符串的子集。例如:
chars <- "test"
value <- "es"
如果“value”作为字符串“chars”的一部分出现,我想返回TRUE。在以下场景中,我想返回false:
chars <- "test"
value <- "et"
答案 0 :(得分:321)
使用grepl
功能
grepl(value, chars)
# TRUE
答案 1 :(得分:123)
叹了口气,我花了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
以linux可执行文件命名,它本身是&#34; G lobal R egular E xpression P rint&#34;,它将读取输入行,然后如果它们与您给出的参数匹配则打印它们。 &#34;全球&#34;意味着匹配可能发生在输入行的任何地方,我将解释&#34;正则表达&#34;下面,但这个想法是匹配字符串的更聪明的方法(R称这个&#34;字符&#34;,例如class("abc")
),&#34;打印&#34;因为它是一个命令行程序,发出输出意味着它打印到它的输出字符串。
现在,grep
程序基本上是一个过滤器,从输入行到输出行。似乎R的grep
函数同样会采用一系列输入。由于我完全不知道的原因(我大约一小时前才开始玩R),它会返回匹配的索引向量,而不是匹配列表。
但是,回到你原来的问题,我们真正想要的是知道我们是否在大海捞针中找到了针,一个真/假值。他们显然决定将这个函数命名为grepl
,就像在&#34; grep&#34;但是&#34; L ogical&#34;返回值(它们调用true和false逻辑值,例如class(TRUE)
)。
所以,现在我们知道这个名字的来源以及它应该做什么。让我们回到正则表达式。参数,即使它们是字符串,它们也用于构建正则表达式(以下称为正则表达式)。正则表达式是一种匹配字符串的方法(如果这个定义让你烦恼,那就让它去)。例如,正则表达式a
匹配字符"a"
,正则表达式a*
匹配字符"a"
0次或更多次,正则表达式a+
将匹配字符"a"
1次或更多次。因此,在上面的示例中,我们正在搜索1+2
的针,当被视为正则表达式时,意味着&#34;一个或多个1后跟一个2&#34; ...但是我们之后是一个加号!
所以,如果你在没有设置grepl
的情况下使用fixed
,那么你的针头会不小心成为干草堆,这会不经常发生,我们可以看到它甚至适用于OP的例。但这是一个潜在的错误!我们需要告诉它输入是字符串,而不是正则表达式,这显然是fixed
的用途。为何固定?毫无头绪,给这个答案添加书签b / c你可能需要再记录5次才能记住它。
您的代码越好,您需要了解的历史记录就越少。每个参数都至少有两个有趣的值(否则它不需要是一个参数),文档在这里列出9个参数,这意味着至少有2 ^ 9 = 512种方式来调用它,编写,测试和记忆的工作很多......解耦这些函数(拆分它们,删除彼此的依赖关系,字符串的东西不同于正则表达式的东西不同于矢量的东西)。有些选项也是相互排斥的,不会给用户提供使用代码的错误方法,即有问题的调用应该是结构上无意义的(例如传递一个不存在的选项),而不是逻辑上无意义的(你必须发出警告来解释它)。比喻一下:用一面墙替换10楼一侧的前门比悬挂一个警告其使用的标志更好,但要么两者都要好。在一个接口中,函数定义了参数应该是什么样子,而不是调用者(因为调用者依赖于函数,推断每个人可能想要调用它的所有内容,使得函数也依赖于调用者,并且这种类型周期性依赖会迅速阻塞系统,永远不会提供你期望的好处)。对于模棱两可的类型要非常警惕,TRUE
和0
以及"abc"
等所有向量都是设计缺陷。
答案 2 :(得分:31)
您想要grepl
:
> chars <- "test"
> value <- "es"
> grepl(value, chars)
[1] TRUE
> chars <- "test"
> value <- "et"
> grepl(value, chars)
[1] FALSE
答案 3 :(得分:21)
使用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
答案 4 :(得分:15)
万一你还要检查一个字符串(或一组字符串)是否包含多个子字符串,你也可以使用'|'在两个子串之间。
>substring="as|at"
>string_vector=c("ass","ear","eye","heat")
>grepl(substring,string_vector)
你会得到
[1] TRUE FALSE FALSE TRUE
因为第一个单词有子串“as”,最后一个单词包含子串“at”
答案 5 :(得分:14)
另外,可以使用&#34; stringr&#34;库:强>
> 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
答案 6 :(得分:8)
使用grep
或grepl
,但要注意您是否要使用正则表达式。
默认情况下,grep
和相关的正则表达式匹配,而不是文字子字符串。如果您没想到,并且尝试匹配无效的正则表达式,则不起作用:
> grep("[", "abc[")
Error in grep("[", "abc[") :
invalid regular expression '[', reason 'Missing ']''
要进行真正的子字符串测试,请使用fixed = TRUE
。
> grep("[", "abc[", fixed = TRUE)
[1] 1
如果你确实想要正则表达式,那很好,但这不是OP似乎要问的问题。
答案 7 :(得分:7)
您可以使用grep
grep("es", "Test")
[1] 1
grep("et", "Test")
integer(0)
答案 8 :(得分:0)
此处存在类似问题:给定字符串和关键字列表,请检测该字符串中包含哪些关键字(如果有)。
此线程的建议建议stringr
的{{1}}和str_detect
。以下是grepl
软件包中的基准测试:
使用
microbenchmark
然后
map_keywords = c("once", "twice", "few")
t = "yes but only a few times"
mapper1 <- function (x) {
r = str_detect(x, map_keywords)
}
mapper2 <- function (x) {
r = sapply(map_keywords, function (k) grepl(k, x, fixed = T))
}
我们找到
microbenchmark(mapper1(t), mapper2(t), times = 5000)
如您所见,在实际的关键字字符串和向量上,使用Unit: microseconds
expr min lq mean median uq max neval
mapper1(t) 26.401 27.988 31.32951 28.8430 29.5225 2091.476 5000
mapper2(t) 19.289 20.767 24.94484 23.7725 24.6220 1011.837 5000
和str_detect
进行了5,000次以上的关键字搜索迭代,grepl
的效果比{{1 }}。
结果是布尔向量grepl
,该布尔向量标识字符串中包含哪些关键字(如果有)。
因此,我建议使用str_detect
来确定字符串中是否包含任何关键字。