Замена запятых в тексте внутри тегов в R - PullRequest
1 голос
/ 29 апреля 2020

У меня есть текстовый файл (my.txt) со следующим содержимым, которое я буду sh обрабатывать в R.

Lorem ipsum tag:[value_0], dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua tag:[value_01, value_02, value_03].
Ut enim ad minim veniam, tag:[value_04, value_05, value_06, value_07] quis nostrud exercitation, tag:[value_08, value_09, value_10].

Я буду sh обрабатывать строки внутри тегов ( tag:[ * ]). Значения внутри тегов разделены запятой и состоят из букв c и знаков препинания (кроме запятых и скобок). Количество значений внутри тега является переменным (1 или более). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Все, что мне удалось выяснить, - это

Lorem ipsum tag:[value_0], dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua tag:[value_01]+[value_02]+[value_03].
Ut enim ad minim veniam, tag:[value_04]+[value_05]+[value_06]+[value_07] quis nostrud exercitation, tag:[value_08]+[value_09]+[value_10].

. для захвата содержимого тегов.

gsub(
  pattern = paste0(
    "tag:\\[([^]]*)\\]"
  ),
  replacement = "\\1",
  x = readLines("my.txt")
)

Я не могу просто найти и заменить запятые, так как за пределами тегов есть запятые. Есть ли способ обработать \\1 для замены запятых на ]+[? Есть ли способ достичь моей цели, используя базу R?

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Вот некоторые решения.

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

1) gsubfn Этот однострочник использует gsubfn, который находит соответствия шаблону, указанному в первом аргументе , передает его функции (которая может быть указана в виде формулы) во втором аргументе и заменяет каждое совпадение выводом функции.

Здесь он соответствует tag:[, за которым следует строка до следующего ближайшего ] и использует gsub для выполнения требуемой замены в этом.

library(gsubfn)

gsubfn("tag:\\[.*?\\]", ~ gsub(", ", "]+[", x), Lines)

2) gsub Это можно сделать за один gsub, хотя обратите внимание на предостережение ниже. Он ищет запятую, за которой следует пробел, за которым следует любое количество не квадратных скобок, за которыми следует правая квадратная скобка. Если левая квадратная скобка стоит первой или правая квадратная скобка не встречается, она не будет совпадать. Все, кроме запятой, находится в пределах просмотра с нулевой шириной - просмотр не будет рассматриваться как часть шаблона, поэтому заменяется только пространство запятых, а часть просмотра продолжает обрабатываться для получения дополнительных последовательностей запятых и пробелов.

(К сожалению, lookbehind не поддерживает повторяющиеся символы, поэтому мы не можем использовать ту же идею для проверки предшествующего tag:[. Таким образом, это не совсем безопасно, хотя проверок, которые действительно кажутся достаточными для примера ввода в вопросе и, возможно, для вашего фактического ввода.)

Используется только база R.

gsub(", (?=[^][]*\\])", "]+[", Lines, perl = TRUE)

2a) Эта вариация (2) длиннее чем (2), но он проверяет tag:[ и все еще использует только основание R. Предполагается, что на входе нет скобок. Если в скобках есть скобки, используйте другие символы, которых нет во вводе, например, <и>. Сначала он заменяет tag:[...] на {...}. Затем он выполняет подстановку, как в (2), но с использованием скобок, и, наконец, преобразует обратно.

Lines2 <- gsub("tag:\\[(.*?)\\]", "{\\1}", Lines)
Lines3 <- gsub(", (?=[^][{}]*})", "]+[", Lines, perl = TRUE)
gsub("\\{(.*?)\\}", "tag:[\\1]", Lines2)
1 голос
/ 29 апреля 2020

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

input <- c(
  "orem ipsum tag:[value_0], dolor sit amet",
  "consectetur adipiscing elit",
  "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua tag:[value_01, value_02, value_03].",
  "Ut enim ad minim veniam, tag:[value_04, value_05, value_06, value_07] quis nostrud exercitation, tag:[value_08, value_09, value_10]."
)

stringr::str_replace_all(input, "tag:\\[[^\\]]*\\]", function(x) {
  stringr::str_replace_all(x, ", ", "]+[")
})

, которая возвращает

[1] "orem ipsum tag:[value_0], dolor sit amet"                                                                                                 
[2] "consectetur adipiscing elit"                                                                                                              
[3] "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua tag:[value_01]+[value_02]+[value_03]."                                  
[4] "Ut enim ad minim veniam, tag:[value_04]+[value_05]+[value_06]+[value_07] quis nostrud exercitation, tag:[value_08]+[value_09]+[value_10]."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...