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

Extracting a number following specific text in R

我有一个数据框,其中有一列全是文本。我需要捕获特定短语后面的数字(可能是长度最有可能是 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 回头看,我有时会通过 mistake.If 获得地块面积,有人可以帮助我使用前瞻性正则表达式或 stringr 中的类似内容,我将不胜感激它。正则表达式对我来说是一个弱点。非常感谢。

你需要 lookbehind 正则表达式。

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)

DEMO

不知道为什么上面的代码不会 return 任何东西。你也可以试试sub

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

以下正则表达式可以帮助您入门:

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

The DEMO.

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

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

提取单词前后数字的常用技巧是匹配所有字符串直到单词或数字或数字和单词同时捕获数字然后匹配字符串的其余部分并使用 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.integeras.numeric)。 \s* 匹配第二个 sub.

中的 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

参见regex demo

您还可以利用来自 stringrstr_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

参见regex demo

正则表达式匹配:

  • (?i) - 以不区分大小写的方式
  • \bfloor area:? - 一个完整的单词(\b 是单词边界)floor area 后跟一个可选的 :(一次或零次出现,? )
  • \s* - 零个或多个空格
  • (\d+) - 第 1 组(将在 [,2] 中)捕获一位或多位数字

R demo online

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

希望对您有所帮助。