【问题标题】:Replacing commas in text inside tags in R在R中的标签内替换文本中的逗号
【发布时间】:2020-08-12 20:14:51
【问题描述】:

我有一个文本文件 (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].

我希望处理标签内的字符串 (tag:[ * ])。 标签内的值是 逗号分隔组成 字母数字字符和标点符号(逗号和括号除外)。 标签内的值的数量是可变的(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 来实现我的目标?

非常感谢。

【问题讨论】:

    标签: r regex string text


    【解决方案1】:

    这里有一些解决方案。

    在问题中,方括号中的逗号后面总是跟一个空格,我认为这是一般情况,但是如果方括号中的逗号后面可以跟一个非空格,那么删除模式中逗号后面的空格在每个解决方案中。

    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)
    

    【讨论】:

    • 已添加变体 2a。
    【解决方案2】:

    您可以通过使用嵌套替换的 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]."
    

    【讨论】:

    • 这是一个非常聪明的解决方案。谢谢。
    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    相关资源
    最近更新 更多