Удалить повторяющиеся элементы в строке с R - PullRequest
0 голосов
/ 20 февраля 2019

Я планирую удалить повторяющиеся элементы (каждый из которых содержит два или более символов) из строк.Например, от "aaa" я ожидаю "aaa", от "aaaa" я ожидаю "aa", от "abababcdcd" I epxect "abcd", от "cdababcdcd" я ожидаю "cdabcd".

Iпопробовал gsub("(.{2,})\\1+","\\1",str).Работает в случаях 1-3, но не работает в случае 4. Как решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

РЕШЕНИЕ

Решение заключается в использовании двигателей регулярного выражения PCRE или ICU, а не TRE.

Используйте любую базу R gsub с perl=TRUE(используется шаблон PCRE regex ) и шаблон "(?s)(.{2,})\\1+" или stringr::str_replace_all() (используется ICU regex engine ) с тем же шаблоном:

> x <- "cdababcdcd"
> gsub("(?s)(.{2,})\\1+", "\\1", x, perl=TRUE)
[1] "cdabcd"
> library(stringr)
> str_replace_all(x, "(?s)(.{2,})\\1+", "\\1")
[1] "cdabcd"

Флаг (?s) необходим, чтобы . соответствовал любому символу, включая символы разрыва строки (в регулярном выражении TRE . соответствует всем символам по умолчанию).

ДЕТАЛИ

Регулярное выражение TRE плохо справляется с "патологическими" случаями, которые в основном связаны с возвратом, который напрямую связан с квантификаторами (я выделил некоторые части):

СоответствиеАлгоритм, используемый в TRE, использует линейное время наихудшего случая по длине искомого текста и квадратичное время наихудшего случая по длине используемого регулярного выражения.Другими словами, временная сложность алгоритма составляет O (M2N) , где M - длина регулярного выражения, а N - длинаtext. Используемое пространство также квадратично по длине регулярного выражения, но не зависит от искомой строки.Это квадратичное поведение имеет место только в патологических случаях, которые, вероятно, очень редки на практике.

Предсказуемая скорость совпадения Из-за алгоритма сопоставления, используемого в TRE, максимальное время, затрачиваемое на любой вызов regexec(), всегда прямо пропорционально длине искомой строки.Есть одно исключение: если используются обратные ссылки, сопоставление может занять время, которое растет экспоненциально с длиной строки. Это потому, что сопоставление обратных ссылок - это полная проблема NP , и почти навернякав наихудшем случае требуется экспоненциальное время для сопоставления.

В тех случаях, когда TRE не удается вычислить все возможности сопоставления строки, она не возвращает совпадения, строка возвращается как есть .Следовательно, в вызове gsub нет никаких изменений.

0 голосов
/ 20 февраля 2019

Так же просто, как: gsub("(.{2,})\\1+","\\1",str, perl = T)

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