Различное поведение базы R gsub и stringr :: str_replace_all? - PullRequest
6 голосов
/ 19 июня 2020

Я ожидал бы, что gsub и stringr::str_replace_all вернут тот же результат в следующем примере, но только gsub вернет желаемый результат. Я разрабатываю урок, чтобы продемонстрировать 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 заменяет только 2017 и 2018, но оставляет остальные, хотя для обоих используется один и тот же 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"

Почему это так?

1 Ответ

8 голосов
/ 19 июня 2020

Это потому, что gsub имеет аргумент perl, установленный по умолчанию на FALSE, тогда как stringr всегда использует TRUE под капотом. Если вы установите perl на TRUE в gsub, результат будет тот же. (v0.3.0)

Если вы хотите использовать stringr, вы можете извлечь искомое выражение, используя str_match в сочетании с опережающими поисками.

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"

Создано 2020-06-19 пакетом REPEX (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...