在R中提取特定文本后面的数字

6
我有一个数据框,其中包含一列文本。我需要捕获跟在特定短语后面的数字(可能是长度为1到4位数的任意数字),即'Floor Area''floor area'。我的数据将类似于以下内容:
"A beautiful flat on the 3rd floor with floor area: 50 sqm and a lift"
"Newbuild flat. Floor Area: 30 sq.m" 
"6 bed house with floor area 50 sqm, lot area 25 sqm"

如果我只尝试提取数字,或者从sqm往回看,有时会错误地得到地块面积。如果有人能帮我使用stringr中的前瞻正则表达式或类似方法,我将不胜感激。对我来说,正则表达式是一个薄弱环节。提前致谢。
5个回答

8
一种常见的技术,用于提取单词前或后的数字,是匹配到单词或数字或数字和单词之前的所有字符串,同时捕获数字,然后匹配剩余的字符串,并使用"sub"替换为已捕获的子字符串。
# Extract the first number after a word:
as.integer(sub(".*?<WORD_OR_PATTERN_HERE>.*?(\\d+).*", "\\1", x))

# Extract the first number after a word:
as.integer(sub(".*?(\\d+)\\s*<WORD_OR_PATTERN_HERE>.*", "\\1", x))

注意:将\\d+替换为\\d+(?:\\.\\d+)?以匹配整数或浮点数(为了与上面的代码保持一致,请记得将as.integer更改为as.numeric)。在第二个sub中,\\s*匹配0个或多个空格。

对于当前情况,可能的解决方案如下:

v <- c("A beautiful flat on the 3rd floor with floor area: 50 sqm and a lift","Newbuild flat. Floor Area: 30 sq.m","6 bed house with floor area 50 sqm, lot area 25 sqm")
as.integer(sub("(?i).*?\\bfloor area:?\\s*(\\d+).*", "\\1", v))
# [1] 50 30 50

请查看正则表达式演示
您还可以使用stringr中的str_match捕获机制并获取第二列值([,2]):
> library(stringr)
> v <- c("A beautiful flat on the 3rd floor with floor area: 50 sqm and a lift","Newbuild flat. Floor Area: 30 sq.m","6 bed house with floor area 50 sqm, lot area 25 sqm")
> as.integer(str_match(v, "(?i)\\bfloor area:?\\s*(\\d+)")[,2])
[1] 50 30 50

请查看正则表达式演示
正则表达式匹配如下内容:
  • (?i) - 不区分大小写
  • \\bfloor area:? - 匹配整个单词(\b为单词边界) floor area,后面跟一个可选的 : (出现一次或零次,?
  • \\s* - 零个或多个空格
  • (\\d+) - 第一组(将在 [,2] 中)捕获一个或多个数字
请查看在线 R 演示

1
太好了。非常感谢,也感谢您详细而友善的解释! - RichS
为了捕获小数,可以将 (\\d+) 替换为 (\\d+(?:.\\d+)),只需记得同时将 as.integer 更改为 as.numeric - JWilliman

0
你需要使用“后顾之忧”正则表达式。
str_extract_all(x, "\\b[Ff]loor [Aa]rea:?\\s*\\K\\d+", perl=T)

或者

str_extract_all(x, "(?i)\\bfloor area:?\\s*\\K\\d+", perl=T)

演示

不知道为什么上面的代码没有返回任何内容。你可以尝试使用sub

> sub(".*\\b[Ff]loor\\s+[Aa]rea:?\\s*(\\d+).*", "\\1", x)
[1] "50" "30" "50"

1
perl 不是 str_extract_all() 的参数。 - Rich Scriven
所以,在 st_extract_all 中不需要 perl arg? - Avinash Raj
对于 'perl=TRUE',会显示 '未使用的参数',而不使用 perl,则只会显示 'character(0)'。 - RichS
@AvinashRaj:最新版本的stringr使用ICU正则表达式库。 :) 它不支持\K - Wiktor Stribiżew
1
谁干的?我要用烂鱼抽 stringr 包的开发者。 - Avinash Raj

0
text<- "A beautiful flat on the 3rd floor with floor area: 50 sqm and a lift"

unique(na.omit(as.numeric(unlist(strsplit(unlist(text), "[^0-9]+")))))
# [1]  3 50

希望这有所帮助。

0

以下正则表达式可能会帮助你入门:

[Ff]loor\s+[Aa]rea:?\s+(\d{1,4})

演示版。


0

使用以下正则表达式进行不区分大小写的匹配:

floor\s*area:?\s*(\d{1,4})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接