使用 stringr 从 R 中的系列中提取最后 4 位数字
Extract last 4-digit number from a series in R using stringr
我想展平从 HTML 表中提取的列表。下面介绍了一个最小的工作示例。该示例取决于 R 中的 stringr
包。第一个示例展示了所需的行为。
years <- c("2005-", "2003-")
unlist(str_extract_all(years,"[[:digit:]]{4}"))
[1] "2005" "2003"
当我尝试匹配一系列其他数字中的最后一个 4 位数字时,下面的示例会产生不良结果。
years1 <- c("2005-", "2003-", "1984-1992, 1996-")
unlist(str_extract_all(years1,"[[:digit:]]{4}$"))
character(0)
据我了解文档,我应该在模式末尾包含 $
以便在字符串末尾请求匹配。我更愿意匹配第二个示例中的数字“2005”、“2003”和“1996”。
\d{4}[^\d]*$
尝试 this.This 应该为 you.See 演示做。
stringi
包具有对字符串的特定部分进行操作的便捷函数。所以你可以找到最后出现的四位连续数字,如下所示。
library(stringi)
x <- c("2005-", "2003-", "1984-1992, 1996-")
stri_extract_last_regex(x, "\d{4}")
# [1] "2005" "2003" "1996"
获得相同结果的其他方法是
stri_sub(x, stri_locate_last_regex(x, "\d{4}"))
# [1] "2005" "2003" "1996"
## or, since these count as words
stri_extract_last_words(x)
# [1] "2005" "2003" "1996"
## or if you prefer a matrix result
stri_match_last_regex(x, "\d{4}")
# [,1]
# [1,] "2005"
# [2,] "2003"
# [3,] "1996"
你可以很容易地使用 base R sub
:
sub('.*(\d{4}).*', '\1', years1)
## [1] "2005" "2003" "1996"
这里要匹配的模式是.*
(任意字符的零个或多个)后跟\d{4}
(四个连续的数字,我们通过括在括号中捕获),后跟零或更多字符。
sub
用第二个参数中的值替换匹配的模式。在这种情况下,\1
表示我们要用第一个捕获的子字符串(即四个连续的数字)替换整个匹配模式。
这里的正则表达式是贪婪的,所以它会绕过 \d{4}
的早期匹配,用 .*
消耗它们。仅捕获四个连续数字的最后一个序列。
字符串结尾 $
锚点断言字符串结尾的位置。
也就是说,正好匹配字符串末尾的四位数字。不幸的是,发生的事情是数字试图匹配,然后正则表达式引擎继续尝试断言该位置并失败,因为没有在这个位置并连续回溯试图匹配它们。
要解决此问题,您可以greed简单地使用所有字符,直到最后一组数字。
years1 <- c('2005-', '2003-', '1984-1992, 1996-')
unlist(str_extract_all(years1, perl('.*\K\d{4}')))
# [1] "2005" "2003" "1996"
我想展平从 HTML 表中提取的列表。下面介绍了一个最小的工作示例。该示例取决于 R 中的 stringr
包。第一个示例展示了所需的行为。
years <- c("2005-", "2003-")
unlist(str_extract_all(years,"[[:digit:]]{4}"))
[1] "2005" "2003"
当我尝试匹配一系列其他数字中的最后一个 4 位数字时,下面的示例会产生不良结果。
years1 <- c("2005-", "2003-", "1984-1992, 1996-")
unlist(str_extract_all(years1,"[[:digit:]]{4}$"))
character(0)
据我了解文档,我应该在模式末尾包含 $
以便在字符串末尾请求匹配。我更愿意匹配第二个示例中的数字“2005”、“2003”和“1996”。
\d{4}[^\d]*$
尝试 this.This 应该为 you.See 演示做。
stringi
包具有对字符串的特定部分进行操作的便捷函数。所以你可以找到最后出现的四位连续数字,如下所示。
library(stringi)
x <- c("2005-", "2003-", "1984-1992, 1996-")
stri_extract_last_regex(x, "\d{4}")
# [1] "2005" "2003" "1996"
获得相同结果的其他方法是
stri_sub(x, stri_locate_last_regex(x, "\d{4}"))
# [1] "2005" "2003" "1996"
## or, since these count as words
stri_extract_last_words(x)
# [1] "2005" "2003" "1996"
## or if you prefer a matrix result
stri_match_last_regex(x, "\d{4}")
# [,1]
# [1,] "2005"
# [2,] "2003"
# [3,] "1996"
你可以很容易地使用 base R sub
:
sub('.*(\d{4}).*', '\1', years1)
## [1] "2005" "2003" "1996"
这里要匹配的模式是.*
(任意字符的零个或多个)后跟\d{4}
(四个连续的数字,我们通过括在括号中捕获),后跟零或更多字符。
sub
用第二个参数中的值替换匹配的模式。在这种情况下,\1
表示我们要用第一个捕获的子字符串(即四个连续的数字)替换整个匹配模式。
这里的正则表达式是贪婪的,所以它会绕过 \d{4}
的早期匹配,用 .*
消耗它们。仅捕获四个连续数字的最后一个序列。
字符串结尾 $
锚点断言字符串结尾的位置。
也就是说,正好匹配字符串末尾的四位数字。不幸的是,发生的事情是数字试图匹配,然后正则表达式引擎继续尝试断言该位置并失败,因为没有在这个位置并连续回溯试图匹配它们。
要解决此问题,您可以greed简单地使用所有字符,直到最后一组数字。
years1 <- c('2005-', '2003-', '1984-1992, 1996-')
unlist(str_extract_all(years1, perl('.*\K\d{4}')))
# [1] "2005" "2003" "1996"