2013-08-15 4 views
5

Мне нужно заменить строку A на строку B, только если строка A является целым словом (например, «MECH»), и я не хочу делать замену, когда A является частью более длинной строки (например, «МЕХАНИЧЕСКИЙ»). До сих пор у меня есть grepl(), который проверяет, является ли строка A цельной строкой, но я не могу понять, как сделать замену. Я добавил ifelse() с идеей сделать замену gsub(), когда grep() возвращает TRUE, иначе не заменяют. Какие-либо предложения? См. Код ниже. Благодарю.Регулярное выражение для поиска и замены условно

aa <- data.frame(type = c("CONSTR", "MECH CONSTRUCTION", "MECHANICAL CONSTRUCTION MECH", "MECH CONSTR", "MECHCONSTRUCTION")) 

from <- c("MECH", "MECHANICAL", "CONSTR", "CONSTRUCTION") 
to <- c("MECHANICAL", "MECHANICAL", "CONSTRUCTION", "CONSTRUCTION") 

gsub2 <- function(pattern, replacement, x, ...) { 
    for(i in 1:length(pattern)){ 
    reg <- paste0("(^", pattern[i], "$)|(^", pattern[i], ")|(", pattern[i], "$)|(", pattern[i], ")") 
    ifelse(grepl(reg, aa$type), 
      x <- gsub(pattern[i], replacement[i], x, ...), 
      aa$type) 
    } 
    x 
} 

aa$title3 <- gsub2(from, to, aa$type) 

ответ

2

Вы можете вложить строки в from векторе в \\< и \\> сопоставлении только целые слов:

x <- c("CONSTR", "MECH CONSTRUCTION", "MECHANICAL CONSTRUCTION MECH", 
     "MECH CONSTR", "MECHCONSTRUCTION") 

from <- c("\\<MECH\\>", "\\<CONSTR\\>") 
to <- c("MECHANICAL", "CONSTRUCTION") 

for(i in 1:length(from)){ 
    x <- gsub(from[i], to[i], x) 
} 

print(x) 
# [1] "CONSTRUCTION"      "MECHANICAL CONSTRUCTION"   
# [3] "MECHANICAL CONSTRUCTION MECHANICAL" "MECHANICAL CONSTRUCTION"   
# [5] "MECHCONSTRUCTION" 
+0

Я заметил, что в элементе 5 он не заменил МЕЧ. Должно ли это быть? –

0

Я использую регулярное выражение (?<=\W|^)MECH(?=\W|$), чтобы получить, если внутри строки содержат слово целиком MECH как this.

Это то, что вам нужно?

0

Только для потомков, кроме использования \< \> корпуса, целое слово может быть определенно как любая строка заканчивается в пространстве или конце строки (\s|$).

gsub("MECH(\\s|$)", "MECHANICAL\\1", aa$type) 

Единственная проблема с этим подходом является то, что вам нужно перенести в пространстве или отслужившей линии, которую вы использовали в качестве части матча, следовательно, инкапсуляции в скобках и обратной ссылке (\1).

Корпус \< \> превосходит этот конкретный вопрос, так как у вас нет особых исключений. Однако, если у вас есть исключения, лучше использовать более явный метод. Чем больше инструментов в вашем инструменте, тем лучше.

+0

или запятая, точка или точка с запятой и т. Д. – eddi

+0

@eddi Да, вам нужно быть явным. Есть и плюсы, и минусы, чтобы быть явным. Это старая гибкость против скорости. – Dinre

Смежные вопросы