r - 基本R gsub和stringr::str_replace_all的不同行为?

标签 r regex stringr string-substitution

我希望gsubstringr::str_replace_all在下面返回相同的结果,但是只有gsub返回预期的结果。我正在开发一个类(class)来演示str_replace_all,所以我想知道为什么它在这里返回不同的结果。

txt <- ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n2017**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n2018**   0.70   0"

gsub(".*2017|2018.*", "", txt)

stringr::str_replace_all(txt, ".*2017|2018.*", "")
gsub返回预期的输出(已删除2017之前和包括的所有内容,以及2018之后和包括的所有内容)。

gsub的输出(预期)
[1] "**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n"

但是str_replace_all仅替换20172018,而其余部分保留,即使两者都使用相同的pattern

str_replace_all的输出(不打算使用)
[1] ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n"

为什么会这样呢?

最佳答案

这是因为gsub默认将其参数perl设置为FALSE,而stringr始终在幕后使用TRUE。如果在perl中将TRUE设置为gsub,将产生相同的结果。

library(stringr)
txt <- ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n2017**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n2018**   0.70   0"

(base <- gsub(".*2017|2018.*", "", txt, perl = TRUE))
#> [1] ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n"

(strng_r <- str_replace_all(txt, ".*2017|2018.*", ""))
#> [1] ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n"

identical(base, strng_r)
#> [1] TRUE

reprex package(v0.3.0)创建于2020-06-19

如果要使用stringr,可以结合使用str_match和lookaheads来提取要查找的表达式。

library(stringr)
txt <- ".72   2.51\n2015**   2.45   2.30   2.00   1.44   1.20   1.54   1.84   1.56   1.94   1.47   0.86   1.01\n2016**   1.53   1.75   2.40   2.62   2.35   2.03   1.25   0.52   0.45   0.56   1.88   1.17\n2017**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50\n2018**   0.70   0"

str_match(txt, "(?<=2017).*.(?=\\n2018)")
#>      [,1]                                                                                    
#> [1,] "**   0.77   0.70   0.74   1.12   0.88   0.79   0.10   0.09   0.32   0.05   0.15   0.50"

reprex package(v0.3.0)创建于2020-06-19

关于r - 基本R gsub和stringr::str_replace_all的不同行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62471164/

相关文章:

Python:在(子)字符串分隔符上分割,但在大括号内时不分割?

python - 使用正则表达式反向搜索

r - 如何从R中的字符串中提取数字?

r - 从列中提取日期并在 R 中缺少年份时添加年份

r - 如何在64位模式下运行sparkR

r - 将arrangeGrob存储到对象,不创建可打印对象

R Shiny : Observe only works once

Java正则表达式错误

regex - 用操纵模式替换多个模式

RGoogleDocs 和现在的 RGoogleData