【问题标题】:Regex for gsub to match line until and through newline \n charactergsub 的正则表达式匹配行直到和通过换行符 \n 字符
【发布时间】:2019-05-22 06:26:21
【问题描述】:

尝试为 R gsub 构建一个正则表达式,以通过要删除的换行符匹配字符串。

示例字符串:

text <- "categories: crime, punishment, france\nTags: valjean, javert,les mis\nAt the end of the day, the criminal Valjean escaped once more."

理想的结果是 gsub 替换前两个文本块,这样剩下的就是后面的文本。

最终,罪犯冉阿让再次逃脱。

摆脱类别和标签。

这是我正在使用的模式:

^categor*.\n{1}

它应该匹配行的开头,单词片段之后的所有内容,直到它到达第一个换行符,但它只匹配片段。我做错了什么?

而且,有没有比两个 gsub 更好的方法来解决这个问题?

【问题讨论】:

  • 预期的输出是最后一个换行符之后的内容?你能发布你想要的作为示例字符串的输出吗?
  • 是这个吗:sub(".*\\n([^\n]*$)", "\\1", text)?

标签: r regex gsub


【解决方案1】:

1) 这里有一些问题,所以第一个选项删除了前两行:

sub("^categor([^\n]*\n){2}", "", text)
## [1] "At the end of the day, the criminal Valjean escaped once more."

如果categor 部分无关紧要,那么这样做:

tail(strsplit(text, "\n")[[1]], -2)
## [1] "At the end of the day, the criminal Valjean escaped once more."

2) 如果想要删除...:....\n 形式的任何行,其中每行冒号前的字符必须是单词字符:

gsub("\\w+:[^\n]+\n", "", text)
## [1] "At the end of the day, the criminal Valjean escaped once more."

gsub("\\w+:.+?\n", "", text)
## [1] "At the end of the day, the criminal Valjean escaped once more."

grep("^\\w+:", unlist(strsplit(text, "\n")), invert = TRUE, value = TRUE)
## [1] "At the end of the day, the criminal Valjean escaped once more."

3) 或者如果我们想删除只有特定标签的行:

gsub("(categories|Tags):.+?\n", "", text)
## [1] "At the end of the day, the criminal Valjean escaped once more."

4)如果您还想捕获标签,使用read.dcf 可能也很有趣。

s <- unlist(strsplit(text, "\n"))
ix <- grep("^\\w+:", s, invert = TRUE)
s[ix] <- paste("Content", s[ix], sep = ": ")
out <- read.dcf(textConnection(s))

给出这个 3 列矩阵:

> out
     categories                  Tags                     
[1,] "crime, punishment, france" "valjean, javert,les mis"
     Content                                                         
[1,] "At the end of the day, the criminal Valjean escaped once more."

【讨论】:

  • tail(., -2) 不是tail(., 1) 更直观吗?
  • 仅当只需要最后一行时。我认为除了前两个之外的所有内容都需要,这在本示例中是相同的,但可能不是。
  • 谢谢!解决方案 2 正是我想要的。
【解决方案2】:

试试这个(换行符与\\n匹配:

gsub("^categor.*\\n",  "", text)
# [1] "At the end of the day, the criminal Valjean escaped once more."

【讨论】:

    【解决方案3】:

    也许是下面的正则表达式:

    sub("^categor.*\\n([^\n]*$)", "\\1", text)
    #[1] "At the end of the day, the criminal Valjean escaped once more."
    

    【讨论】:

      【解决方案4】:

      无需使用[^\n],因为您可以仅使用. 来匹配除换行符之外的任何内容。请注意,您需要将 (?n) 修饰符与 TRE 一起使用(默认正则表达式引擎使用 (g)sub/(g)regexpr),并且使用 perl=TRUE,这是默认的 . 行为:

      text <- "categories: crime, punishment, france\nTags: valjean, javert,les mis\nAt the end of the day, the criminal Valjean escaped once more."
      sub("(?n)^categor(?:.*\n){2}", "", text)
      sub("^categor(?:.*\n){2}", "", text, perl=TRUE)
      

      这里,如果字符串以categor 开头,则删除前两行。

      请参阅R demo online

      模式详情

      • ^ - 字符串锚的开始
      • categor - 文字子串
      • (?:.*\n){2} - 恰好连续出现 2 次 ({2}) 任何字符,但换行符 (.) 零次或多次 (*) 后跟一个 LF 字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-21
        • 2010-11-13
        • 1970-01-01
        相关资源
        最近更新 更多