-->

测试如果字符是一个字符串测试如果字符是一个字符串(Test if characters are in

2019-05-13 12:30发布

我试图确定一个字符串是另一个字符串的子集。 例如:

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

我想返回TRUE,如果“值”显示为字符串“字符”的一部分。 在下列情况下,我会想返回false:

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

Answer 1:

使用grepl功能

grepl(value, chars)
# TRUE


Answer 2:

回答

叹了口气,我花了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可执行文件的名字命名,这本身就是“G叶形[R egularé上的表达P RINT”的缩写,它会读取输入的线,然后打印出来,如果他们匹配你给的参数。 “环球”意味着可以在输入行的任何地方发生的比赛中,我将解释“正则表达式”的,但这个想法是这是一个聪明的方式来匹配字符串(R称此为“人物”,例如class("abc") ),以及“打印”,因为它是一个命令行程序,发射输出装置将其打印到它的输出字符串。

现在, grep程序基本上是一个过滤器,从输入的线,以输出线。 它似乎是R的grep功能同样需要输入数组。 对于那些完全不知道的我的原因(我只开始前有R玩一个小时左右),则返回匹配的索引的矢量,而不是匹配的列表。

但是,回到你原来的问题,我们真正想要的是知道我们是否找到了干草堆,真/假值针。 他们显然决定命名这个功能grepl ,如“grep的”,而是用“L ogical”返回值(他们称之为真假逻辑值,例如class(TRUE)

所以,现在我们知道了名字的由来和它应该做的事。 让我们回到正则表达式。 论点,即使他们是字符串,它们被用来构建正则表达式(以下简称:正则表达式)。 一个正则表达式是一个方法来匹配字符串(如果这个定义会刺激你,让它去)。 例如,正则表达式a字符匹配"a" ,正则表达式a*的字符相匹配"a"为0或更多次,以及正则表达式a+将匹配的字符"a" 1次或多次。 因此,在上面的例子中,我们针正在寻找1+2 ,当为正则表达式处理,是指“一个或多个1后跟2” ......但我们的后面是一个加号!

所以,如果你使用的grepl没有设置fixed ,你的针会不小心将草堆,这将意外地工作很多时候,我们可以看到它甚至还可以在OP的例子。 但是,这是一个潜在的错误! 我们需要告诉它的输入是一个字符串,而不是一个正则表达式,这显然是什么fixed为。 为什么固定? 没有线索,书签这个答案B / C,你可能将不得不5次看它,你把它记住了。

最后几点想法

你的代码是更好的,你有更少的历史,知道它的意义。 每个参数可以至少有两个有趣的值(否则它不会需要是一个参数),文件清单这里9个参数,这意味着有至少2 ^ 9 = 512点的方式来调用它,这是一个很多工作编写,测试和记忆......这样的分离功能(拆分起来,对方删除相关性,串东西是不同的正则表达式比东西比矢量的东西不同)。 一些选项也相互排斥,不给用户不正确的方式使用的代码,即有问题的调用应该是结构上没有意义的(如通过不存在的选项),而不是逻辑上无意义(在那里你必须发出警告来解释它)。 把比喻:与墙10楼的侧面更换前门是不是挂,警告反对使用一个标志更好,但无论是比不变好。 在接口方面,函数定义的参数应该是什么样子,而不是调用(因为调用者依赖于功能,推断,每个人都可能曾经想用做功能依赖于呼叫者也叫它一切,这种类型周期性的依赖将迅速堵塞系统并永远为您所期望的利益)。 要十分小心模棱两可类型的,这是一个设计缺陷,事情像TRUE0"abc"都是向量。



Answer 3:

你想grepl

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


Answer 4:

使用这个函数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


Answer 5:

万一你还要检查是否一个字符串(或一组字符串)包含(S)的多个子串,你也可以用“|” 2子之间。

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

你会得到

[1]  TRUE FALSE FALSE  TRUE

因为第一个字有子“为”,而最后一个字包含子“在”



Answer 6:

另外,可以做到用“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


Answer 7:

使用grepgrepl 但要注意你是否要使用正则表达式

默认情况下, grep和相关的花费正则表达式匹配,而不是一个文字串。 如果你不希望的是,并尝试匹配的正则表达式无效,这是行不通的:

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

要做到真正的测试子,使用fixed = TRUE

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

如果你想正则表达式,伟大的,但是这不是要问什么会出现OP。



Answer 8:

您可以使用grep

grep("es", "Test")
[1] 1
grep("et", "Test")
integer(0)


文章来源: Test if characters are in a string