#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"