从R中的字符串中删除括号和文本

aio*_*ias 30 r

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

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

我想用括号删除文本,最后得到以下列表:

                  Name
1        Company A Inc 
2            Company B
3       Company C Inc.
4       Company D Inc.
5            Company E
Run Code Online (Sandbox Code Playgroud)

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

companies$Name <- as.character(companies$Name)
c<-strsplit(companies$Name, "\\(")
ldply(c)
Run Code Online (Sandbox Code Playgroud)

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

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

我没有和strsplit解决方案结婚.无论删除该文本和括号都没关系.

MrF*_*ick 45

A gsub应该在这里工作

gsub("\\s*\\([^\\)]+\\)","",as.character(companies$Name))

# [1] "Company A Inc"  "Company B"      "Company C Inc."
# [4] "Company D Inc." "Company E" 
Run Code Online (Sandbox Code Playgroud)

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

  • **注意**:要确保只删除字符串末尾的括号,请使用 `gsub("\\s*\\([^\\)]+\\)\\s*$" ,"",as.character(companys$Name))` (2认同)

Ric*_*ven 9

您可以使用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, " \\(.*\\)", "")
# [1] "Company A Inc"  "Company B"      "Company C Inc." 
# [4] "Company D Inc." "Company E"
Run Code Online (Sandbox Code Playgroud)

而且,如果您仍然想使用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" 
Run Code Online (Sandbox Code Playgroud)


Wik*_*żew 8

如果括号是配对且平衡的,则可以使用

gsub("\\s*(\\([^()]*(?:(?1)[^()]*)*\\))", "", x, perl=TRUE)
Run Code Online (Sandbox Code Playgroud)

在线查看正则表达式R 演示

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)
Run Code Online (Sandbox Code Playgroud)

输出:

[1] "Company A Inc"  "Company B"      "Company C Inc." "Company D Inc."
[5] "Company E"     
Run Code Online (Sandbox Code Playgroud)

正则表达式详细信息

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


akr*_*run 5

你也可以使用:

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
Run Code Online (Sandbox Code Playgroud)


GKi*_*GKi 5

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

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

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

sub("\\(.*)", "", c("ab (cd) ef", "(ij) kl"))
#[1] "ab  ef" " kl"   
Run Code Online (Sandbox Code Playgroud)

如果有多个括号:

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

(需要转义\\(.意味着一切,*意味着重复 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"    
Run Code Online (Sandbox Code Playgroud)

如果有嵌套括号:

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

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