regex 只提取字符串中与R中的正则表达式模式匹配的部分

kknvjkwl  于 2022-11-18  发布在  其他
关注(0)|答案(3)|浏览(148)

我构建了一个从网页上自动抓取的数据框,其中一个变量是文本形式“May 12”中的日期。
然而,有时候观察结果会在日期之后附上一些字符(有时候是奇怪的字符),例如:“May 20 Other ",“Dez 1”,“Oct 12 ABCdáé"。对于这些情况,我希望将值替换为正确的字符,如:“12月24日”、“10月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+"

我真的不明白我必须在替换参数中包括什么来删除坏字符,如果它们存在的话。

9gm1akwq

9gm1akwq1#

我添加了一个捕获组和一个反向引用"\\1"

sub("^([A-Z]{1}[a-z]{2}\\s\\d+).*", "\\1", vector)
[1] "May 20" "Dez 1"  "Oct 12"

replacement参数接受'\\1'之类的反向引用,但不是您使用的典型正则表达式模式。反向引用指的是您创建的模式和定义的捕获组。在本例中,我们的捕获组是缩写的month和day,我们用parenthetics(..)来概括。当"\\1"放置在取代参数中时,会传回这些括号内撷取的任何文字。
这个quick-start guide可能会有帮助

nbnkbykc

nbnkbykc2#

我们也可以试试

sub("\\s*[^0-9]+$", "", vector)
#[1] "May 20" "Dez 1"  "Oct 12"
6xfqseft

6xfqseft3#

如果其他人对这些不同方法的性能感兴趣,这里有一个可重复的示例,将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日创建

相关问题