将括号/括号内的数字增加指定数量的功能

时间:2019-07-05 17:05:54

标签: r regex

我有一个这种形式的字符串。我想将此字符串中括号内的数字增加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 个答案:

答案 0 :(得分:4)

gsubfngsub相似,只是替换字符串是替换 function ,该替换 function 将匹配项作为输入,并将其替换为输出。可以使用公式符号(如此处所示)或常用功能符号来表示函数。

内部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]"

答案 1 :(得分:3)

类似于@G。格洛腾迪克的答案也可以通过stringr的{​​{1}}函数轻松实现,该函数接受替换函数而不是常量。在这种情况下,只需要一个函数调用:

str_replace_all

输出:

library(stringr)

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

或者是Base R解决方案:

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

输出:

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

注释:

  1. 正则表达式[1] " John was going .[16] Sam was Walking [17,18]. Rita was reading [19] . Donald was cooking with 3 spoons [20-22]" 匹配任何数字一次或多次(\\d+(?=[^[]*\\])),然后跟(\\d+)一系列非开括号字符零或更多次((?=...))和右括号([^[]*)。有效地仅匹配​​括号内的数字。

  2. \\]使用正则表达式并返回gregexpr中的所有匹配位置。 String启用环视功能。

  3. perl = TRUE占据regmatches返回的位置,并返回实际的匹配字符串。

  4. 第二次调用gregexpr用于用regmatches

  5. 中的新值替换括号中的数字。

答案 2 :(得分:0)

我的猜测是,也许我们可以使用此表达式进行统计以捕获数字:

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

然后,我们只需在其中添加15个。

如果您有兴趣,可以在this demo的右侧面板中进一步解释该表达式。

答案 3 :(得分:0)

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]