仅提取与 R 中的正则表达式模式匹配的字符串部分
Extract just the part of string that matches a regex pattern in R
我构建了一个从网页自动废弃的数据框,其中一个变量是文本形式“5 月 12 日”中的日期。
然而,有时观察结果会在日期后附加一些字符(在某些情况下是奇怪的字符),例如:“May 20 õ”、"Dez 1"、"Oct 12ABCdáé"。
对于这些情况,我想用正确的字符替换该值,因此:“Dec 24”、“Oct 1”。
在谷歌 多次搜索解决方案并尝试以下功能后:sub、gsub 和 grep,我找不到找到正确功能的方法。
我发现正则表达式的学习曲线很陡峭,但在使用该工具后 http://regexr.com/ 我可以定义正则表达式以匹配出现问题的观察中的模式。 ([A-Z]{1}[a-z]{2})\s\d+.*
此刻,我有以下例子:
vector = c("May 20", "Dez 1", "Oct 12ABCdáé”)
我最后尝试的解决方案是:
dateformat = gsub(pattern = "([A-Z]{1}[a-z]{2})\s\d+.*", replacement = "([A-Z]{1}[a-z]{2})\s\d+", x = vector)
当然,这让我用文本字符串“([A-Z]{1}[a-z]{2})\s\d+”替换了它们中的每一个。
> dateformat
[1] "([A-Z]{1}[a-z]{2})sd+" "([A-Z]{1}[a-z]{2})sd+"
[3] "([A-Z]{1}[a-z]{2})sd+"
我真的不明白我必须在替换参数中包含什么来删除坏字符(如果它们存在的话)。
我添加了一个捕获组和一个反向引用"\1"
:
sub("^([A-Z]{1}[a-z]{2}\s\d+).*", "\1", vector)
[1] "May 20" "Dez 1" "Oct 12"
替换参数接受像 '\1'
这样的反向引用,但不接受您使用的典型正则表达式模式。反向引用指回您创建的模式和您定义的捕获组。在这种情况下,我们的捕获组是我们用附加符号 (..)
概述的缩写月份和日期。当将 "\1"
放在替换参数中时,将返回这些括号内捕获的任何文本。
这个quick-start guide可能会有帮助
我们也可以试试
sub("\s*[^0-9]+$", "", vector)
#[1] "May 20" "Dez 1" "Oct 12"
如果其他人对这些不同方法的性能感兴趣,这里有一个可重复的示例,比较 Pierre 的 方法与 akrun 的 方法.
这表明 akrun 的 方法更快:
library(microbenchmark)
set.seed(1234)
# Original poster's data
# vector <- c("May 20", "Dez 1", "Oct 12ABCdáé")
# Increased the size to 200
vector <- sample(c("May 20", "Dez 1", "Oct 12ABCdáé"), 200L, replace = TRUE)
# Comparison of timings with 10000 repetitions
microbenchmark(
pierre_l = sub("^([A-Z]{1}[a-z]{2}\s\d+).*", "\1", vector),
akrun = sub("\s*[^0-9]+$", "", vector),
times = 10000L
)
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> pierre_l 164.201 169.201 233.5096 173.302 220.2515 17809.1 10000
#> akrun 159.001 164.202 228.9020 168.200 212.7010 13443.5 10000
由 reprex package (v2.0.1)
于 2022 年 3 月 24 日创建
我构建了一个从网页自动废弃的数据框,其中一个变量是文本形式“5 月 12 日”中的日期。
然而,有时观察结果会在日期后附加一些字符(在某些情况下是奇怪的字符),例如:“May 20 õ”、"Dez 1"、"Oct 12ABCdáé"。 对于这些情况,我想用正确的字符替换该值,因此:“Dec 24”、“Oct 1”。
在谷歌 多次搜索解决方案并尝试以下功能后:sub、gsub 和 grep,我找不到找到正确功能的方法。
我发现正则表达式的学习曲线很陡峭,但在使用该工具后 http://regexr.com/ 我可以定义正则表达式以匹配出现问题的观察中的模式。 ([A-Z]{1}[a-z]{2})\s\d+.*
此刻,我有以下例子:
vector = c("May 20", "Dez 1", "Oct 12ABCdáé”)
我最后尝试的解决方案是:
dateformat = gsub(pattern = "([A-Z]{1}[a-z]{2})\s\d+.*", replacement = "([A-Z]{1}[a-z]{2})\s\d+", x = vector)
当然,这让我用文本字符串“([A-Z]{1}[a-z]{2})\s\d+”替换了它们中的每一个。
> dateformat
[1] "([A-Z]{1}[a-z]{2})sd+" "([A-Z]{1}[a-z]{2})sd+"
[3] "([A-Z]{1}[a-z]{2})sd+"
我真的不明白我必须在替换参数中包含什么来删除坏字符(如果它们存在的话)。
我添加了一个捕获组和一个反向引用"\1"
:
sub("^([A-Z]{1}[a-z]{2}\s\d+).*", "\1", vector)
[1] "May 20" "Dez 1" "Oct 12"
替换参数接受像 '\1'
这样的反向引用,但不接受您使用的典型正则表达式模式。反向引用指回您创建的模式和您定义的捕获组。在这种情况下,我们的捕获组是我们用附加符号 (..)
概述的缩写月份和日期。当将 "\1"
放在替换参数中时,将返回这些括号内捕获的任何文本。
这个quick-start guide可能会有帮助
我们也可以试试
sub("\s*[^0-9]+$", "", vector)
#[1] "May 20" "Dez 1" "Oct 12"
如果其他人对这些不同方法的性能感兴趣,这里有一个可重复的示例,比较 Pierre 的 方法与 akrun 的 方法.
这表明 akrun 的 方法更快:
library(microbenchmark)
set.seed(1234)
# Original poster's data
# vector <- c("May 20", "Dez 1", "Oct 12ABCdáé")
# Increased the size to 200
vector <- sample(c("May 20", "Dez 1", "Oct 12ABCdáé"), 200L, replace = TRUE)
# Comparison of timings with 10000 repetitions
microbenchmark(
pierre_l = sub("^([A-Z]{1}[a-z]{2}\s\d+).*", "\1", vector),
akrun = sub("\s*[^0-9]+$", "", vector),
times = 10000L
)
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> pierre_l 164.201 169.201 233.5096 173.302 220.2515 17809.1 10000
#> akrun 159.001 164.202 228.9020 168.200 212.7010 13443.5 10000
由 reprex package (v2.0.1)
于 2022 年 3 月 24 日创建