Функция для увеличения чисел в скобках / скобках на указанную величину - PullRequest
0 голосов
/ 05 июля 2019

У меня есть строка этой формы. Я хочу увеличить числа в скобках в этой строке на 15.

Пожалуйста, предложите некоторый код регулярного выражения в R для этой задачи. Читал о извлечении чисел из скобок / скобок на этом форуме. Но не помогает в этом конкретном случае.

String=
" John was going .[1]  Sam was Walking [2,3]. Rita was reading [4] . Donald was cooking with 3 spoons [5-7]"

Желаемый выход.

"John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] Donald was cooking with 3 spoons [20-22]"

Ответы [ 4 ]

4 голосов
/ 05 июля 2019

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

Внутренний gsubfn принимает строку [...] и заменяет числа в ней на эти числа плюс 15, а внешний gsubfn передает [...] внутреннему.Обратите внимание, что регулярное выражение \\[.*?\\] соответствует левой квадратной скобке \\[, за которой следует самая короткая строка .*? до следующей правой квадратной скобки \\].

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

library(gsubfn)

gsubfn("\\[.*?\\]", ~ gsubfn("\\d+", ~ as.numeric(x) + 15, x), String)
## " John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 3 spoons [20-22]"

Если достаточно увеличить все числа, то это можно упростить до:

gsubfn("\\d+", ~ as.numeric(x) + 15, String)
## [1] " John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 18 spoons [20-22]"
3 голосов
/ 05 июля 2019

Аналогично @G. Ответ Гротендика, этого также легко добиться с помощью функции stringr str_replace_all, которая принимает функцию замены, а не константу. В этом случае требуется только один вызов функции:

library(stringr)

str_replace_all(String, "\\d+(?=[^\\[]*\\])", function(x) as.numeric(x) + 15)

Выход:

[1] " John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 3 spoons [20-22]"

Или, альтернативно, решение Base R:

pos <- gregexpr("\\d+(?=[^[]*\\])", String, perl = TRUE)
num <- as.numeric(regmatches(String, pos)[[1]]) + 15
regmatches(String, pos)[[1]] <- num

Выход:

[1] " John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 3 spoons [20-22]"

Примечания:

  1. Регулярное выражение \\d+(?=[^[]*\\]) соответствует любым цифрам один или несколько раз (\\d+), за которыми следует ((?=...)) серия символов без открывающей скобки ноль или более раз ([^[]*) ) и закрывающая скобка (\\]). Это эффективно соответствует только цифрам в скобках.

  2. gregexpr принимает регулярное выражение и возвращает все совпадающие позиции в пределах String. perl = TRUE включает обходные пути.

  3. regmatches принимает позиции, возвращаемые gregexpr, и возвращает действительные совпадающие строки.

  4. Второй вызов regmatches используется для замены цифр в скобках новым значением из num

0 голосов
/ 05 июля 2019
s = "John was going .[1]  Sam was Walking [2,3]. Rita was reading [4] . Donald was cooking with 3 spoons [5-7]"

import re

s = re.sub(r'\[([\d,-]+)\]', lambda g: re.sub(r'\d+', lambda gg: str(int(gg.group(0)) + 15), g.group(0)), s)

print(s)

Отпечатки:

John was going .[16]  Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 3 spoons [20-22]
0 голосов
/ 05 июля 2019

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

\[(\d+(?:[,-]\d+)?)\]

, тогда мы просто добавили бы к ним 15.

На правой панели это демо , выражение будет дополнительно объяснено, если вам может быть интересно.

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