Удаление круглых скобок и текста внутри из строк в R

#r #regex #gsub

#r #регулярное выражение

Вопрос:

В 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. Все, что удаляет этот текст и круглые скобки, будет в порядке.

Комментарии:

1. Также смотрите bracketX в qdap пакете.

Ответ №1:

Здесь gsub должно работать

 gsub("\s*\([^\)] \)","",as.character(companies$Name))
# or using "raw" strings as of R 4.0
gsub(r"{s*([^)] )}","",as.character(companies$Name))

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

Здесь мы просто заменяем вхождения «(…)» ничем (также удаляя все начальные пробелы). R делает его хуже, чем он есть, со всеми экранированиями, которые мы должны делать для круглых скобок, поскольку они являются специальными символами в регулярных выражениях.

Комментарии:

1. Почему вы использовали [^\)] между круглыми скобками?

2. @rrs Я хотел сопоставить все символы, не закрывающие круглые скобки. Я думаю, что не жадный .*? тоже будет работать, но если я знаю единственное, что может завершить мой блок совпадений, мне нравится использовать это явно.

3. ПРИМЕЧАНИЕ : Чтобы убедиться, что удалены только те круглые скобки, которые находятся в конце строки, используйте gsub("\s*\([^\)] \)\s*$","",as.character(companies$Name))

Ответ №2:

Вы могли бы использовать 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" 
 

Ответ №3:

Вы также можете использовать:

 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
 

Комментарии:

1. Этот код не оставляет места после удаления значения в () . Могу ли я узнать, есть ли у вас какое-либо решение для этого? Я бы хотел оставить один пробел

2. @ZahraHnn Если вы проверяете код, это " (" попытка, "(" не уверенная в вашем случае, хотя и без воспроизводимого примера

3. это не сработает, на самом деле я хочу удалить смайлики, которые похожи на <f0><ed><f8>; используя: GEnx(mytext$text, «<«, «>»), в тех случаях, когда между текстом и эмодзи нет пробела, результат будет неудовлетворительным. например, учитывая этот текст «Я был так<f0><ed><f8>, чтобы увидеть тебя <f0><ee> <ed>» , пользователь использовал эмодзи без пробела, и когда я удалил <><><> результаты похожи на «… чтобы увидеть …» ,но я ожидал «… итак, чтобы увидеть … »

Ответ №4:

Если круглые скобки парные и сбалансированные, вы можете использовать

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

Смотрите демонстрацию регулярных выражений и 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)
 

Вывод:

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

Подробности регулярного выражения

  • s* — ноль или более пробелов
  • (([^()]*(?:(?1)[^()]*)*)) — Захват группы 1 (требуется для повторного использования части шаблона между круглыми скобками):
    • ( ( символ
    • [^()]* — ноль или более символов, отличных от ( и )
    • (?:(?1)[^()]*)* — ноль или более вхождений всего шаблона группы 1 ( (?1) является подпрограммой регулярных выражений, повторяющей шаблон группы 1), а затем ноль или более символов, отличных от ( и )
    • ) ) символ.

Ответ №5:

В вашем случае это приведет к желаемому результату, если вы удалите все, начиная с ( .

 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, ? означает, что не жадно удалять не все от первого до последнего совпадения.

В качестве альтернативы вы можете использовать [^)] то, что означает все, но не a ) .

 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 .

Ответ №6:

 library(qdap)
bracketX(companies$Name) -> companies$Name
 

Комментарии:

1. Не могли бы вы, пожалуйста, объяснить свой ответ?

Ответ №7:

Другое gsub решение: замените термин в скобках, которым предшествует необязательный пробел , на "" , т.е. пустую строку

 gsub("(\s*\(\w \))", "", companies$Name)

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