r заменить текст в строке таблицей поиска - PullRequest
0 голосов
/ 27 апреля 2018

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

У меня есть (на самом деле намного больше) текстовая строка, которая выглядит следующим образом:

string <- "Test test [438] test. Test 299, test [82]."

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

lookup <- read.table(text = "
Number   orderedNbr
1 270 1
2 299 2
3 82  3
4 314 4
5 438 5", header = TRUE)

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

pattern <- "\\[(\\d+)\\]"

Теперь я огляделся по сторонам и попробовал sub / gsub, lapply, merge, str_replace, но не смог заставить его работать ... Я не знаю, как сказать R! посмотреть, что находится в скобках, найти тот же аргумент в таблице поиска и выдать то, что стоит в следующем столбце.

Надеюсь, вы мне поможете, и это не очень глупый вопрос. Thx

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Считайте свою таблицу ключей и значений (таблица из 2 столбцов) в кадр данных. Если вашей исходной информацией является простой текстовый файл, вы можете легко использовать read.csv для получения фрейма данных. В приведенном ниже примере я жестко закодирую фрейм данных с двумя записями. Затем я перебираю его и делаю замены во входной строке.

df <- data.frame(keys=c(438, 82), values=c(5, 3))
string <- "Test test [438] test. Test [82]."
for (i in 1:nrow(df)) {
    string <- gsub(paste0("(?<=\\[)", df$keys[i], "(?=\\])"), df$values[i], string, perl=TRUE)
}

string

[1] "Test test 5 test. Test 3."

Демо

Примечание. Как мудро указывал @Frank, мое решение не сработало бы, если бы у ваших числовых маркеров (например, [438]) были замены, которые являются номерами, которые также появляются в качестве других маркеров. То есть, если замена ключа значением приводит к появлению еще одного ключа, могут возникнуть проблемы. Если бы это было возможно, я бы предложил использовать маркеры, для которых это не может произойти. Например, вы можете снять скобки после каждой замены.

0 голосов
/ 27 апреля 2018

Вы можете использовать regmatches<- с шаблоном, содержащим lookahead / lookbehind:

patt = "(?<=\\[)\\d+(?=\\])"
m = gregexpr(patt, string, perl=TRUE)
v = as.integer(unlist(regmatches(string, m)))

`regmatches<-`(string, m, value = list(lookup$orderedNbr[match(v, lookup$Number)]))
# [1] "Test test [5] test. Test 299, test [3]."

Или для непосредственного изменения строки измените последнюю строку на более читаемую ...

regmatches(string, m) <- list(lookup$orderedNbr[match(v, lookup$Number)])
0 голосов
/ 27 апреля 2018

Мы можем использовать регулярное выражение, чтобы соответствовать только числам, которые заключены в квадратную скобку

library(gsubfn)
gsubfn("(?<=\\[)(\\d+)(?=\\])", setNames(as.list(lookup$orderedNbr), 
             lookup$Number), string, perl = TRUE)
#[1] "Test test [5] test. Test [3]."

Или без регулярного выражения, используя paste, заключив квадратную скобку в каждый столбец 'lookup'

gsubfn("(\\[\\d+\\])", setNames(as.list(paste0("[", lookup$orderedNbr, 
          "]")), paste0("[", lookup$Number, "]")), string)
...