【问题标题】:Remove parentheses and text within from strings in R从R中的字符串中删除括号和文本
【发布时间】:2014-08-02 02:48:17
【问题描述】:

在 R 中,我有一个公司列表,例如:

companies  <-  data.frame(Name=c("Company A Inc (COMPA)","Company B (BEELINE)", "Company C Inc. (Coco)", "Company D Inc.", "Company E"))

我想删除带括号的文本,最终得到以下列表:

                  Name
1        Company A Inc 
2            Company B
3       Company C Inc.
4       Company D Inc.
5            Company E

我尝试的一种方法是拆分字符串,然后使用 ldply:

companies$Name <- as.character(companies$Name)
c<-strsplit(companies$Name, "\\(")
ldply(c)

但由于并非所有公司名称都有括号部分,所以它失败了:

Error in list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor) : 
  Results do not have equal lengths

我没有嫁给 strsplit 解决方案。无论删除该文本和括号都可以。

【问题讨论】:

  • 另见qdap包中的bracketX

标签: r regex


【解决方案1】:

在你的情况下,它会达到预期的结果,如果你删除以 ( 开头的所有内容。

sub(" \\(.*", "", companies$Name)
#[1] "Company A Inc"  "Company B"      "Company C Inc." "Company D Inc." "Company E"     

从字符串中删除括号和文本,您可以使用。

sub("\\(.*)", "", c("ab (cd) ef", "(ij) kl"))
#[1] "ab  ef" " kl"   

如果有多个括号:

gsub("\\(.*?)", "", c("ab (cd) ef (gh)", "(ij) kl"))
#[1] "ab  ef " " kl"    

( 需要转义 \\(. 表示所有内容,* 表示重复 0 到 n,? 表示不贪心从第一个匹配到最后一个匹配项中删除所有内容。

作为替代方案,您可以使用 [^)] 什么意思,但不是 )

sub("\\([^)]*)", "", c("ab (cd) ef", "(ij) kl"))
#[1] "ab  ef" " kl"   

gsub("\\([^)]*)", "", c("ab (cd) ef (gh)", "(ij) kl"))
#[1] "ab  ef " " kl"    

如果有嵌套括号:

gsub("\\(([^()]|(?R))*\\)", "", c("ab ((cd) ef) gh (ij)", "(ij) kl"), perl=TRUE)
#[1] "ab  gh " " kl"

其中a(?R)z 是一个递归,它匹配一个或多个字母a,后跟完全相同数量的字母z

【讨论】:

    【解决方案2】:

    如果括号成对且平衡,则可以使用

    gsub("\\s*(\\([^()]*(?:(?1)[^()]*)*\\))", "", x, perl=TRUE)
    

    参见regexR demo online

    companies  <-  data.frame(Name=c("Company A Inc (COMPA)","Company B (BEELINE)", "Company C Inc. (Coco)", "Company D Inc.", "Company E"))
    gsub("\\s*(\\([^()]*(?:(?1)[^()]*)*\\))", "", companies$Name, perl=TRUE)
    

    输出:

    [1] "Company A Inc"  "Company B"      "Company C Inc." "Company D Inc."
    [5] "Company E"     
    

    正则表达式详细信息

    • \s* - 零个或多个空格
    • (\([^()]*(?:(?1)[^()]*)*\)) - 捕获组 1(需要递归括号之间的模式部分):
      • \( - 一个 ( 字符
      • [^()]* - 除了 () 之外的零个或多个字符
      • (?:(?1)[^()]*)* - 整个第 1 组模式出现零次或多次((?1) 是递归第 1 组模式的正则表达式子例程),然后出现零个或多个除 () 之外的字符
      • \) - ) 字符。

    【讨论】:

      【解决方案3】:

      您可以使用stringr::str_replace。这很好,因为它接受因子变量。

      companies <- data.frame(Name=c("Company A Inc (COMPA)","Company B (BEELINE)", 
                                     "Company C Inc. (Coco)", "Company D Inc.", 
                                     "Company E"))
      
      library(stringr)
      str_replace(companies$Name, " \\s*\\([^\\)]+\\)", "")
      # [1] "Company A Inc"  "Company B"      "Company C Inc." 
      # [4] "Company D Inc." "Company E"
      

      如果你仍然想使用strsplit,你可以这样做

      companies$Name <- as.character(companies$Name)
      unlist(strsplit(companies$Name, " \\(.*\\)"))
      # [1] "Company A Inc"  "Company B"      "Company C Inc."
      # [4] "Company D Inc." "Company E" 
      

      【讨论】:

        【解决方案4】:

        另一个gsub 解决方案:用"" 替换前面带有可选空格的括号中的术语,即空字符串

        gsub("(\\s*\\(\\w+\\))", "", companies$Name)
        
        [1] "Company A Inc"  "Company B"      "Company C Inc." "Company D Inc."
        [5] "Company E" 
        

        【讨论】:

          【解决方案5】:
          library(qdap)
          bracketX(companies$Name) -> companies$Name
          

          【讨论】:

          • 你能解释一下你的答案吗?
          【解决方案6】:

          你也可以使用:

          library(qdap)
          companies$Name <-  genX(companies$Name, " (", ")")
          
          companies
                  Name
          1  Company A Inc
          2       CompanyB
          3 Company C Inc.
          4 Company D Inc.
          5       CompanyE
          

          【讨论】:

          • 此代码在 () 中的值被删除后不会留下任何空格。我可以知道你是否有任何解决方案?我想留下一个空格
          • @ZahraHnn 如果你检查代码是" (" 试试"(" 虽然没有可重复的例子,但不确定你的情况
          • 那行不通,实际上我想删除类似于 ; 的表情符号;使用:genX(mytext$text, ""),在文本和表情符号之间没有空格的情况下,结果将不能令人满意。例如,考虑到这个文本 "I was soto see you" ,用户使用没有空格的表情符号,当我删除 结果就像“... soto see ...”,但我期待“... so to see ...”
          【解决方案7】:

          gsub 应该在这里工作

          gsub("\\s*\\([^\\)]+\\)","",as.character(companies$Name))
          
          # [1] "Company A Inc"  "Company B"      "Company C Inc."
          # [4] "Company D Inc." "Company E" 
          

          这里我们只是用空替换出现的“(...)”(同时删除任何前导空格)。 R 使它看起来比我们必须为括号做的所有转义更糟糕,因为它们是正则表达式中的特殊字符。

          【讨论】:

          • 你为什么在括号之间使用[^\\)]+
          • @rrs 我想匹配所有非右括号字符。我认为非贪婪的.*? 也可以,但如果我知道唯一可以结束我的匹配块的东西,我喜欢明确地使用它。
          • 注意:要确保只删除字符串末尾的括号,请使用gsub("\\s*\\([^\\)]+\\)\\s*$","",as.character(companies$Name))
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-16
          • 2012-03-16
          • 2012-01-28
          相关资源
          最近更新 更多