替换R中标记内文本中的逗号

替换R中标记内文本中的逗号,r,regex,string,text,R,Regex,String,Text,我有一个文本文件(my.txt),其中包含我希望在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, v

我有一个文本文件(
my.txt
),其中包含我希望在
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].
我希望处理标记内的字符串(
标记:[*]
)。 标记中的值是 逗号分隔的由 字母数字字符和标点符号(逗号和括号除外)。 标记中的值数是可变的(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
以将逗号替换为
]+[
? 有没有一种方法可以使用base R实现我的目标


非常感谢。

您可以使用嵌套替换使用
stringr
包来完成此操作。首先找到标记,然后为每个标记替换逗号。
str\u replace\u 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)gsubfn这一行程序使用
gsubfn
查找与第一个参数中给定模式的匹配项,将其传递给第二个参数中的函数(可以指定为公式),并用函数的输出替换每个匹配项

在这里,它匹配
标记:[
后接一个字符串,直到下一个最近的
]
,并使用
gsub
在其中执行所需的替换

library(gsubfn)

gsubfn("tag:\\[.*?\\]", ~ gsub(", ", "]+[", x), Lines)
2)gsub它可以在一个
gsub
中完成,但请注意下面的警告。它查找逗号,后跟空格,后跟任意数量的非方括号,后跟右方括号。如果左方括号在先,或者没有遇到右方括号,则它将不匹配。除了逗号以外的所有内容都将匹配空格在零宽度的前向范围内——前向不会被视为模式的一部分,因此只替换逗号空格,并继续处理前向部分以获得更多的逗号和空格字符序列

(不幸的是,lookbehind不支持重复字符,因此我们不能使用相同的方法来检查前面的
标记:[
。因此,这不是完全安全的,尽管检查对于问题中的示例输入和您的实际输入似乎是足够的。)

这只使用基本R

gsub(", (?=[^][]*\\])", "]+[", Lines, perl = TRUE)
2a)这个(2)的变体比(2)长,但它确实检查了
标记:[
,并且仍然只使用基数R。它假设输入中没有大括号。如果有大括号,则使用输入中没有的其他字符,例如<和>。首先,它将
标记:[……]
替换为
{…}
。然后它执行(2)中的替换,但使用大括号,最后转换回来

Lines2 <- gsub("tag:\\[(.*?)\\]", "{\\1}", Lines)
Lines3 <- gsub(", (?=[^][{}]*})", "]+[", Lines, perl = TRUE)
gsub("\\{(.*?)\\}", "tag:[\\1]", Lines2)

Lines2这是一个非常聪明的解决方案。谢谢。添加了变体2a。
Lines2 <- gsub("tag:\\[(.*?)\\]", "{\\1}", Lines)
Lines3 <- gsub(", (?=[^][{}]*})", "]+[", Lines, perl = TRUE)
gsub("\\{(.*?)\\}", "tag:[\\1]", Lines2)