在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解决方案结婚。无论删除该文本和括号都没关系。
答案 0 :(得分:37)
gsub
应该在这里工作
gsub("\\s*\\([^\\)]+\\)","",as.character(companies$Name))
# [1] "Company A Inc" "Company B" "Company C Inc."
# [4] "Company D Inc." "Company E"
这里我们只更换“(...)”的出现(也删除任何前导空格)。由于它们是正则表达式中的特殊字符,所以R使它看起来比我们必须对括号进行的所有转义更糟糕。
答案 1 :(得分:7)
您可以使用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"
如果您仍想使用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"
答案 2 :(得分: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
答案 3 :(得分: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"
答案 4 :(得分:1)
如果括号是成对且平衡的,则可以使用
gsub("\\s*(\\([^()]*(?:(?1)[^()]*)*\\))", "", x, perl=TRUE)
请参见regex和R 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组模式的regex子例程),然后为除(
和{{ 1}} )
-一个\)
字符。答案 5 :(得分:0)
library(qdap)
bracketX(companies$Name) -> companies$Name
答案 6 :(得分:0)
另一种gsub
解决方案:用""
将括号中的术语替换为可选空格,即空字符串
gsub("(\\s*\\(\\w+\\))", "", companies$Name)
[1] "Company A Inc" "Company B" "Company C Inc." "Company D Inc."
[5] "Company E"