在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使得它看起来比我们必须为括号所做的所有转义更糟糕,因为它们是正则表达式中的特殊字符.
您可以使用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)
如果括号是配对且平衡的,则可以使用
gsub("\\s*(\\([^()]*(?:(?1)[^()]*)*\\))", "", x, perl=TRUE)
Run Code Online (Sandbox Code Playgroud)
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 组模式的正则表达式子例程),然后是除 和 之外的零个或多个(
字符)
\)
- 一个)
字符。你也可以使用:
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)
在你的情况下,它会达到预期的结果,只要你删除以 开头的所有内容 (
。
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
。
归档时间: |
|
查看次数: |
28745 次 |
最近记录: |