使用通配符进行模式匹配

时间:2011-04-28 18:47:47

标签: r pattern-matching wildcard

如何使用通配符识别字符串?

我找到glob2rx,但我不太明白如何使用它。我尝试使用以下代码来选择以单词blue开头的数据框行:

# make data frame
a <- data.frame( x =  c('red','blue1','blue2', 'red2'))

# 1
result <- subset(a, x == glob2rx("blue*") )

# 2
test = ls(pattern = glob2rx("blue*"))
result2 <- subset(a, x == test )

# 3
result3 <- subset(a, x == pattern("blue*") )

然而,这些都没有奏效。我不确定我是否应该使用不同的功能来尝试这样做。

6 个答案:

答案 0 :(得分:41)

如果要检查数据框内的元素,则不应使用ls(),它仅查看当前工作空间中对象的名称(或者如果在当前环境中的函数内使用)。 ls()不能看到此类对象中的Rownames或元素(除非您在ls(.) - 调用中添加环境参数)。尝试使用grep()这是用于角色向量模式匹配的主力函数:

result <- a[ grep("blue", a$x) , ]  # Note need to use `a$` to get at the `x`

如果你想使用子集,那么可以考虑在子集参数中使用返回逻辑向量的密切相关的函数grepl()

subset(a, grepl("blue", a$x))
      x
2 blue1
3 blue2

编辑:在subset()中添加一个“正确”使用glob2rx:

result <- subset(a,  grepl(glob2rx("blue*") , x) )
result
      x
2 blue1
3 blue2

在我回到这个问题之前,我认为我实际上并不理解glob2rx。 (我确实理解了提问者难以解决的范围问题。任何阅读此内容的人现在应该向下滚动到Gavin的答案并提出它。)

答案 1 :(得分:31)

glob2rx()将包含通配符的模式转换为等效的正则表达式。然后,您需要将此正则表达式传递给R的模式匹配工具之一。

如果您想匹配"blue*"其中*具有通常的通配符 not 正则表达式,则表示我们使用glob2rx()将通配符模式转换为有用的正则表达式:

> glob2rx("blue*")
[1] "^blue"

返回的对象正则表达式。

鉴于您的数据:

x <- c('red','blue1','blue2', 'red2')

我们可以使用grep()或类似工具进行模式匹配:

> grx <- glob2rx("blue*")
> grep(grx, x)
[1] 2 3
> grep(grx, x, value = TRUE)
[1] "blue1" "blue2"
> grepl(grx, x)
[1] FALSE  TRUE  TRUE FALSE

关于您发布的选择行问题

> a <- data.frame(x =  c('red','blue1','blue2', 'red2'))
> with(a, a[grepl(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2
> with(a, a[grep(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2

或通过subset()

> with(a, subset(a, subset = grepl(grx, x)))
      x
2 blue1
3 blue2

希望能解释grob2rx()做什么以及如何使用它?

答案 2 :(得分:4)

您走在正确的轨道上 - 您应该使用Google搜索的关键字是正则表达式。 R使用grep()和其他一些替代方案以比这更直接的方式支持它们。

以下是详细讨论:http://www.regular-expressions.info/rlanguage.html

答案 3 :(得分:2)

如果您确实想要使用通配符来识别特定变量,那么您可以使用ls()grep()的组合,如下所示:

  

l = ls()
  vars.with.result <- l[grep("result", l)]

答案 4 :(得分:2)

你也可以使用package data.table和它的Like函数,详情如下 How to select R data.table rows based on substring match (a la SQL like)

答案 5 :(得分:0)

实现所需功能的另一种方法是通过 dplyr()

filter(str_detect(a, "blue"))

它将考虑 blue 的所有实例,例如 blue1blue2

这个命令与

基本相同
filter(str_detect(a, "blue") == TRUE)

如果蓝调是大写和小写,您可以执行以下操作:

filter(str_detect(str_to_lower(a), "blue"))

我希望它可以帮助正在寻找类似解决方案的人。