Регулярное выражение для перемещения всех экземпляров подстроки в начало - PullRequest
2 голосов
/ 01 апреля 2019

Я пытаюсь переместить все вхождения определенного шаблона в начало строки.Например, если шаблон 'pat' , то я бы хотел, чтобы моя подстановка регулярных выражений конвертировала

'a pat b pat c pat d'

до

'pat pat pat abc d'

Я мог бы добиться этого, неоднократно применяя

string <- gsub(x=string,pattern='(.*)(pat )(.*)',replacement='\\2\\1\\3')

к моей исходной строкезначение, но это требует циклического перебора строки произвольное количество раз, так как я не знаю, сколько раз ожидать, что шаблон будет встречаться в строке.Я также не могу просто использовать жадный подход, например применять подстановку столько раз, сколько длина строки, поскольку я работаю с чрезвычайно длинными векторами строк разной длины и применяю подстановки векторов.

Итак,Есть ли способ достичь этой функциональности с помощью одного выражения регулярного выражения?

РЕДАКТИРОВАТЬ

Похоже, что это невозможно сделать с помощью одного выражения регулярного выражения / gsub,Я должен предоставить более подробную информацию о том, почему это именно то, что мне нужно, когда другие решения будут делать в более ограниченных случаях:

Я работаю с большим набором данных (миллионы строк), содержащим строковое поле, на котором яхотите выполнить правила уборки.Эти правила состоят из списка замен регулярных выражений, указанных в отдельном файле;Есть несколько сотен из них.Процесс очистки выполняется путем зацикливания правил регулярных выражений и применения каждого ко всему строковому столбцу через векторизованную версию gsub.

Для некоторых из этих правил, но не для всех, я хотел бы определить все экземпляры.определенного шаблона, затем переместите все такие экземпляры в начало строки.Указанный шаблон будет меняться от одного правила к другому, и поэтому ни одно решение, которое использует детали искомого шаблона, не является приемлемым.

Похоже, что я не смогу достичь своей цели без серьезной перестройки процесса, если у кого-то нет умных идей ...

Ответы [ 3 ]

1 голос
/ 01 апреля 2019

Фиксированная строка

Предполагая, что шаблон является фиксированной строкой (что имеет место в примере в вопросе), вычислите число повторений шаблона и используйте strrep, чтобы создать столько повторений шаблона, добавляя его к исходной строке. без рисунка:

pat <- "pat"
pats <- paste0(" *", pat, " *")

paste0(strrep(paste0(pat, " "), lengths(gregexpr(pats, x))), gsub(pats, " ", x))
## [1] "pat pat pat a b c d" "pat pat pat a b c d"

Общая схема

Если шаблон не является фиксированной строкой, извлеките его и вставьте перед исходной строкой без него.

library(gsubfn)
paste(sapply(strapply(x, pat), paste, collapse = " "), gsub(pats, " ", x))
## [1] "pat pat pat a b c d" "pat pat pat a b c d"

Примечание

Входные данные - это символьный вектор:

x <- 'a pat b pat c pat d'
x <- c(x, x)
1 голос
/ 01 апреля 2019

Вы можете попробовать что-то очень наивное, как показано ниже:

s <- 'a pat b pat c pat d'
s <- unlist(strsplit(s, " "))
stringtomatch <- "pat"
paste(c(s[grepl(stringtomatch, s)], s[!grepl(stringtomatch, s)]), collapse = " ")
[1] "pat pat pat a b c d"

или посмотрите на regex для расширенных вариантов использования

0 голосов
/ 02 апреля 2019

Это не единственный эксперимент с регулярным выражением, но вы также можете попробовать пакет stringr, так как функции в stringr pacakge векторизованы по string и pattern.

library(stringr)
my_str <- 'a pat b pat c pat d'
my_pat <- c("pat")

# Capture the sepcified pattern
s1 <- unlist(lapply(str_extract_all(my_str, my_pat), FUN = function(x) paste(x, collapse = " ")))

# Remove the captured patterns from the string
s2 <- str_remove_all(my_str, my_pat)

# Move the first pattern to the beginning
str_c(s1, s2, sep = " ")
[1] "pat pat pat a  b  c  d"

По-прежнему работает с векторными строками и шаблонами:

library(stringr)
my_str <- c('a pat b pat c pat d', 'x pet y pet zz pet')
my_pat <- c("pat", 'pet')

# Capture the sepcified pattern
s1 <- unlist(lapply(str_extract_all(my_str, my_pat), FUN = function(x) paste(x, collapse = " ")))

# Remove the captured patterns from the string
s2 <- str_remove_all(my_str, my_pat)

# Move the first pattern to the beginning
str_c(s1, s2, sep = " ")
[1] "pat pat pat a  b  c  d" "pet pet pet x  y  zz " 
...