R正则表达式从字符串中提取信息

时间:2015-01-20 03:21:28

标签: python regex r

有人告诉我R是一个很好的数据处理工具。所以我试图弄清楚是否可以(简单)用R进行正则表达式数据提取。

以下是Python提供两个关键信息的示例:

import re

str = "oh, 100.0 dollar is 621.5 yuan"
m = re.search("([\d+\.\d+]+).*?([\d+\.\d+]+)",str)
if m:
    print m.group(1),"->",m.group(2)

Python的输出是:

100.0 -> 621.5

Python的结果真的很酷,但如何在R中有效地做到?

4 个答案:

答案 0 :(得分:6)

不确定。这样的东西也很容易使用基础R或其中的一个包。以下是" stringi"的示例。封装

library(stringi)
m <- stri_extract_all_regex(str, "\\d+\\.\\d")[[1]]
sprintf("%s -> %s", m[1], m[2])
# [1] "100.0 -> 621.5"

上述R的基础R可能是gregexprregmatches

regmatches(str, gregexpr("\\d+\\.\\d+", str))[[1]]
# [1] "100.0" "621.5"

答案 1 :(得分:6)

好吧,你的正则表达式不正确,并且符合你的预期。 character class定义了一组字符。说 - &#34;匹配类&#34;指定的一个字符。

因此,它匹配以下内容:

[\d+\.\d+]+   # any character of: digits (0-9), '+', '\.', digits (0-9), '+' 
              # (1 or more times)

使用基数R,您可以使用regmatchesgregexpr以下模式:

x <- 'oh, 100.0 dollar is 621.5 yuan'
m <- regmatches(x, gregexpr('\\d+(?:\\.\\d+)?', x, perl=T))[[1]]
paste(m[1], '->', m[2])
# [1] "100.0 -> 621.5"

正则表达式(解释

\d+           # digits (0-9) (1 or more times)
(?:           # group, but do not capture (optional):
  \.          #   '.'
  \d+         #   digits (0-9) (1 or more times)
)?            # end of grouping

答案 2 :(得分:3)

以下是一些方法。其他包装也可能与其他各种包装一起使用。

1)可以使用strapply在一行中完成(尽管为了便于阅读,我们会将其分为两行)。 strapply将模式pat应用于字符串str,然后将捕获的字符串输入到函数中(在此处以公式表示法表示)并返回结果:

library(gsubfn)

# test data
str <- "oh, 100.0 dollar is 621.5 yuan"

pat <- "([\\d+\\.\\d+]+).*?([\\d+\\.\\d+]+)"   
strapply(str, pat, ~ paste(x, "->", y), simplify = TRUE)

,并提供:

[1] "100.0 -> 621.5"

注意我们使用与问题中相同的正则表达式来表明python正则表达式也适用于R(虽然我们需要在写出时加倍反斜杠,因为“\\”代表一个反斜杠);但是,我们可以通过使用它来简化正则表达式:

pat <- "(\\d+\\.\\d+).*?(\\d+\\.\\d+)"   

或者这可能就足够了:

pat <- "([\\d.]+).*?([\\d.]+)"

在随后的几点中,我们使用更简单的正则表达式。

2)我们也可以像这样简化模式,在这种情况下,这可以使用同一个包中的strapplyc

s <- strapplyc(str, "\\d+\\.\\d+")[[1]]
paste(s[1], "->", s[2])

给出相同的答案。

3)另一种方法是将输入分成单词,然后只保留表示数字的单词。这个不使用任何包:

g <- grep("\\d+\\.\\d+", strsplit(str, " ")[[1]], value = TRUE)
paste(g[1], "->", g[2])

给出相同的答案。

答案 3 :(得分:0)

以下是一系列gsub函数。

> str = "oh, 100.0 dollar is 621.5 yuan"
> sub("[[:space:]]+", " -> ", gsub("^[[:space:]]+|[[:space:]]+$", "", gsub("(\\d+(?:\\.\\d+)?)|\\S", '\\1', str, perl=T)))
[1] "100.0 -> 621.5"

如果输入包含两个以上的数字,请尝试此操作。我刚刚用sub

替换了上面的gsub函数
> str = "oh, 100.0 dollar is 621.5 yuan 700 to 888.78"
> gsub("[[:space:]]+", " -> ", gsub("^[[:space:]]+|[[:space:]]+$", "", gsub("(\\d+(?:\\.\\d+)?)|\\S", '\\1', str, perl=T)))
[1] "100.0 -> 621.5 -> 700 -> 888.78"

[[:space:]]+ POSIX字符类,它匹配一个或多个空格。