mik*_*ike 248 regex string r r-faq
我正在尝试确定字符串是否是另一个字符串的子集.例如:
chars <- "test"
value <- "es"
Run Code Online (Sandbox Code Playgroud)
如果"value"作为字符串"chars"的一部分出现,我想返回TRUE.在以下场景中,我想返回false:
chars <- "test"
value <- "et"
Run Code Online (Sandbox Code Playgroud)
小智 345
使用该 grepl
功能
grepl(value, chars)
# TRUE
Run Code Online (Sandbox Code Playgroud)
Jos*_*eek 139
叹了口气,我花了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
Run Code Online (Sandbox Code Playgroud)
grep
Linux的可执行文件的名字命名,这本身就是"的缩写摹叶形[R egular é上的表达P RINT",它会读取输入的线,然后打印出来,如果他们匹配你给的参数."全局"意味着匹配可能出现在输入行的任何地方,我将在下面解释"正则表达式",但这个想法是匹配字符串(R称为"字符",例如class("abc")
)和"打印"的更智能方式"因为它是一个命令行程序,发出输出意味着它打印到它的输出字符串.
现在,该grep
程序基本上是一个过滤器,从输入行到输出行.似乎R的grep
功能同样需要一系列输入.由于我完全不知道的原因(我大约一小时前才开始玩R),它会返回匹配的索引向量,而不是匹配列表.
但是,回到你原来的问题,我们真正想要的是知道我们是否在大海捞针中找到了针,一个真/假值.他们显然决定命名这个功能grepl
,如"grep的",而是用" 大号 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楼一侧的前门比悬挂一个警告其使用的标志更好,但要么两者都要好.在一个接口中,函数定义了参数应该是什么样子,而不是调用者(因为调用者依赖于函数,推断每个人可能想要调用它的所有内容,使得函数也依赖于调用者,并且这种类型周期性依赖会迅速阻塞系统,永远不会提供你期望的好处).要十分小心模棱两可类型的,这是一个设计缺陷,之类的东西TRUE
和0
和"abc"
都是向量.
Jus*_*tin 32
你想要grepl
:
> chars <- "test"
> value <- "es"
> grepl(value, chars)
[1] TRUE
> chars <- "test"
> value <- "et"
> grepl(value, chars)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
bar*_*nus 25
从stringi
包中使用此功能:
> stri_detect_fixed("test",c("et","es"))
[1] FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
一些基准:
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
Run Code Online (Sandbox Code Playgroud)
Sur*_*rya 18
另外,可以使用"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
Run Code Online (Sandbox Code Playgroud)
C. *_*eng 17
如果你还想检查一个字符串(或一组字符串)是否包含多个子字符串,你也可以使用'|' 两个子串之间.
>substring="as|at"
>string_vector=c("ass","ear","eye","heat")
>grepl(substring,string_vector)
Run Code Online (Sandbox Code Playgroud)
你会得到
[1] TRUE FALSE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
因为第一个单词有子串"as",最后一个单词包含子串"at"
使用grep
或grepl
但是要知道您是否要使用正则表达式.
默认情况下,grep
相关的正则表达式匹配,而不是文字子字符串.如果您没有预料到这一点,并且您尝试匹配无效的正则表达式,则它不起作用:
> grep("[", "abc[")
Error in grep("[", "abc[") :
invalid regular expression '[', reason 'Missing ']''
Run Code Online (Sandbox Code Playgroud)
要进行真正的子串测试,请使用fixed = TRUE
.
> grep("[", "abc[", fixed = TRUE)
[1] 1
Run Code Online (Sandbox Code Playgroud)
如果你确实想要正则表达式,那很好,但这不是OP似乎要问的问题.
您可以使用 grep
grep("es", "Test")
[1] 1
grep("et", "Test")
integer(0)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
391655 次 |
最近记录: |