有人告诉我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中有效地做到?
答案 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可能是gregexpr
和regmatches
:
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,您可以使用regmatches
和gregexpr
以下模式:
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字符类,它匹配一个或多个空格。