R:使用rvest从Web提取的字符串上的stringr的str_extract意外行为

时间:2017-07-11 13:47:28

标签: r string rvest stringr

我知道这是一个非常奇怪的例子,但它 可重现:

我有一个简单的正则表达式模式来提取一个人的身高:

pattern <- "1\\.[0-9]{2} m"

测试了一个简单的字符串:

library(stringr)
str_extract("1.75 m", pattern)
[1] "1.75 m"

然而,它并没有处理我从维基百科中搜集的字符串,比如使用html_text中的rvest来提取Linda Evangelista的身高:

library(rvest)
url <- "https://en.wikipedia.org/wiki/Linda_Evangelista"
text <- read_html(url) %>%
  html_nodes(".infobox") %>%
  html_text()
text
[1] "Linda Evangelista\n\nEvangelista in August 2004\n\nBorn\n(1965-05-10) May 10, 1965 (age 52)St. Catharines, Ontario, Canada\nOccupation\nModel\nYears active\n1984–1998 (retired)\n2001–present\nSpouse(s)\nGérald Marie\n(m. 1987; div. 1993)\nChildren\n1\nModeling information\nHeight\n5 ft 9 in (1.75 m)[1]\nHair color\nBrown\nEye color\nBlue-green\nManager\nDNA Model Management (New York)Models 1 (London)\nView Management (Barcelona)\nPriscilla's Model Management (Sydney)\n\n"

str_extract(text, pattern)
[1] NA

但是,如果仔细观察,"1.75 m"字符串就在那里。

可以肯定的是,如果我手动将上述字符串复制粘贴到新变量中,str_extract将按预期工作:

text_manual <- "Linda Evangelista\n\nEvangelista in August 2004\n\nBorn\n(1965-05-10) May 10, 1965 (age 52)St. Catharines, Ontario, Canada\nOccupation\nModel\nYears active\n1984–1998 (retired)\n2001–present\nSpouse(s)\nGérald Marie\n(m. 1987; div. 1993)\nChildren\n1\nModeling information\nHeight\n5 ft 9 in (1.75 m)[1]\nHair color\nBrown\nEye color\nBlue-green\nManager\nDNA Model Management (New York)Models 1 (London)\nView Management (Barcelona)\nPriscilla's Model Management (Sydney)\n\n"
str_extract(text_manual, pattern)
[1] "1.75 m"

注意text个变量都是简单的字符串:

class(text)
[1] "character"
typeof(text)
[1] "character"
class(text_manual)
[1] "character"
typeof(text_manual)
[1] "character"

但他们是一样的吗?号:

text == text_manual
[1] FALSE

他们似乎在第83个角色上有所不同:

str_sub(text, 1, 82) == str_sub(text_manual, 1, 82)
[1] TRUE
str_sub(text, 1, 83) == str_sub(text_manual, 1, 83)
[1] FALSE

但我不知道为什么,它们看起来是一样的,最后一个角色是两个空间:

str_sub(text, 1, 83)
[1] "Linda Evangelista\n\nEvangelista in August 2004\n\nBorn\n(1965-05-10) May 10, 1965 (age "
str_sub(text_manual, 1, 83)
[1] "Linda Evangelista\n\nEvangelista in August 2004\n\nBorn\n(1965-05-10) May 10, 1965 (age "

我考虑在Github上的stringr包中打开一个问题,但我不确定它是stringr还是rvest问题。

任何人都可能知道这里的问题是什么?

1 个答案:

答案 0 :(得分:3)

这两个字符串是不同的,因为它们的编码方式不同:

Encoding(text)
#> [1] "UTF-8"
Encoding(text_manual)
#> [1] "latin1"

utf8ToInt(str_sub(text, 83, 83))
#> [1] 160
utf8ToInt(str_sub(text_manual, 83, 83))
#> [1] 32

intToUtf8(utf8ToInt(str_sub(text, 83, 83)))
#> [1] " "
intToUtf8(utf8ToInt(str_sub(text_manual, 83, 83)))
#> [1] " "

(请注意,Encoding(text_manual)的结果可能会根据您的语言区域进行更改)

要避免此问题,请使用\s中的reg-exp来匹配任何空格字符:

library(rvest)
library(stringr)
url <- "https://en.wikipedia.org/wiki/Linda_Evangelista"
text <- read_html(url) %>%
    html_nodes(".infobox") %>%
    html_text()

pattern <- "1\\.[0-9]{2}\\sm"

str_extract(text, pattern)
#> [1] "1.75 m"