【问题标题】:only remove punctuation for words not numbers只删除单词而不是数字的标点符号
【发布时间】:2021-06-11 06:17:28
【问题描述】:

我正在使用 R 中的 tm 包来删除标点符号。

TextDoc <- tm_map(TextDoc, removePunctuation)

有没有一种方法可以只删除与字母/单词而不是数字有关的标点符号?

例如

我想要performance. --&gt; performance 但我想要3.14 --&gt; 3.14

我希望函数如何工作的示例:

wall, --> wall
expression. --> expression
ef. --> ef
A. --> A
name: --> name
:ok --> ok

91.8.10 --> 91.8.10

编辑:

TextDoc 的形式为:

【问题讨论】:

  • 您如何准确定义“如果它与字母/单词有关”?如果您可以在 reproducible data format 中包含更多可用于测试的测试用例,将会很有帮助。
  • 已更新示例

标签: r regex


【解决方案1】:

您也可以试试这个gsub('(?&lt;!\\d)[[:punct:]](?=\\D)?', '', text, perl = T),其中 text 是您的文本向量。正则表达式的解释

  • (?&lt;!\\d) 任何数字字符的负向回溯
  • [[:punct:]] 搜索标点符号
  • (?=\\D) 后跟任何非数字字符的正向前瞻
  • ? 0 或一次
  • check this 用于正则表达式演示
text <- c("wall, 88.1", "expression.", "ef.", ":ok", "A.", "3.14", "91.8.10")

gsub('(?<!\\d)[[:punct:]](?=\\D)?', '', text, perl = T)
#> [1] "wall 88.1"  "expression" "ef"         "ok"         "A"         
#> [6] "3.14"       "91.8.10"


long_text <- "wall, 88.1 expression. ef. :ok A. 3.14 91.8.10"

gsub('(?<!\\d)[[:punct:]](?=\\D)?', '', long_text, perl = T)
#> [1] "wall 88.1 expression ef ok A 3.14 91.8.10"

reprex package (v2.0.0) 于 2021-06-13 创建

【讨论】:

    【解决方案2】:

    我已根据您的规范和Anil's answer below 彻底修改了我的答案,这比我原来的适用范围更广。

    library(tm)
    
    # Here we pretend that your texts are like this
    text <- c("wall,", "expression.", "ef.", ":ok", "A.", "3.14", "91.8.10",
              "w.a.ll, 6513.645+1646-5")
    
    # and we create a corpus with them, like the one you show
    corp <- Corpus(VectorSource(text))
    
    # you create a function with any of the solutions that we've provided here
    # I'm taking AnilGoyal's because it's better than my rushed purrr one.
    
    my_remove_punct <- function(x) {
      
      gsub('(?<!\\d)[[:punct:]](?=\\D)?', '', x, perl = T)
    
    }
    
    # pass the function to tm_map
    new_corp <- tm_map(corp, my_remove_punct)
    
    # Applying the function will give you a warning about dropping documents; but it's a bug of the TM package.
    
    
    # We use this to confirm that the contents are indeed correct. The last line is a print-out of all the individual documents together.
    sapply(new_corp, print)
    #> [1] "wall"
    #> [1] "expression"
    #> [1] "ef"
    #> [1] "ok"
    #> [1] "A"
    #> [1] "3.14"
    #> [1] "91.8.10"
    #> [1] "wall 6513.645+1646-5"
    #> [1] "wall"                 "expression"           "ef"                  
    #> [4] "ok"                   "A"                    "3.14"                
    #> [7] "91.8.10"              "wall 6513.645+1646-5"
    

    您收到的有关“丢弃文档”的警告并不真实,您可以通过打印看到。解释在this other SO question

    请注意,将来您可以通过向您的对象提供带有函数dput 的原始数据来快速获得更好的答案。像dput(TextDoc) 这样的东西。如果太多,您可以对其进行子集化。

    【讨论】:

    • 感谢您的帮助,如何将您的代码应用到我的数据集 TextDoc 所在的表单中?
    • @user11015000,现在通过实际使用 tm 包进行更新。
    【解决方案3】:

    试图让它不那么难看,但这是我最好的选择:

    library(data.table)
    
    TextDoc <- data.table(text = c("wall",
                          "expression.", 
                          "ef.",
                          "91.8.10",
                          "A.", 
                          "name:", 
                          ":ok"))
    
    TextDoc[grepl("[a-zA-Z]", text), 
          text := unlist(tm_map(Corpus(VectorSource(as.vector(text))), removePunctuation))[1:length(grepl("[a-zA-Z]", text))]]   
    

    这给了我们:

    > TextDoc
             text
    1:       wall
    2: expression
    3:         ef
    4:    91.8.10
    5:          A
    6:       name
    7:         ok
      
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多