R:str_extract 来自 stringr 在使用 rvest 从网络中提取的字符串上的意外行为
R: Unexpected behavior of str_extract from stringr on a string extracted from the web with rvest
我知道这是一个非常奇怪的例子,但它是可重现的:
我有一个简单的正则表达式模式来提取一个人的身高:
pattern <- "1\.[0-9]{2} m"
在一个简单的字符串上测试它有效:
library(stringr)
str_extract("1.75 m", pattern)
[1] "1.75 m"
但是,它不适用于我从维基百科抓取的字符串,比如提取 Linda Evangelista 的身高,使用 rvest
中的 html_text
:
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
但我不知道为什么,它们看起来一样,最后一个字符在两者中都是 space:
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
问题。
有人可能知道这里的问题是什么吗?
这两个字符串不同,因为它们的编码不同:
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)
的结果可能会根据您的区域设置而变化)
为避免此问题,请在 reg-exp
中使用 \s
来匹配任何空白字符:
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"
我知道这是一个非常奇怪的例子,但它是可重现的:
我有一个简单的正则表达式模式来提取一个人的身高:
pattern <- "1\.[0-9]{2} m"
在一个简单的字符串上测试它有效:
library(stringr)
str_extract("1.75 m", pattern)
[1] "1.75 m"
但是,它不适用于我从维基百科抓取的字符串,比如提取 Linda Evangelista 的身高,使用 rvest
中的 html_text
:
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
但我不知道为什么,它们看起来一样,最后一个字符在两者中都是 space:
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
问题。
有人可能知道这里的问题是什么吗?
这两个字符串不同,因为它们的编码不同:
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)
的结果可能会根据您的区域设置而变化)
为避免此问题,请在 reg-exp
中使用 \s
来匹配任何空白字符:
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"