2013-08-15 12 views
5

Muszę zastąpić ciąg A ciągiem B, tylko gdy ciąg A jest całym wyrazem (np. "MECH"), i nie chcę wykonać zamiennika, gdy A jest częścią dłuższego ciągu (np. "MECHANICZNY"). Do tej pory mam grepl(), który sprawdza, czy ciąg A jest ciągiem całkowitym, ale nie mogę wymyślić, jak dokonać wymiany. Dodałem ifelse() z pomysłem, aby dokonać wymiany gsub(), gdy grep() zwróci TRUE, w przeciwnym razie nie zastąpi. Jakieś sugestie? Zobacz poniższy kod. Dzięki.Wyrażenie regularne do znajdowania i zamiany warunkowo

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) 

Odpowiedz

2

można ująć za sznurki w from wektora w \\< i \\> dopasować tylko całe słowa:

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

Zauważyłem w elemencie 5, że nie zastąpił MECH. Czy powinien to mieć? –

0

używam regex (?<=\W|^)MECH(?=\W|$) dostać jeśli wewnątrz łańcucha zawierają cały wyraz MECH jak this.

Czy tego właśnie potrzebujesz?

0

Tylko dla potomności, innych niż przy użyciu obudowy \< \>, całe słowo można zdefiniować jako dowolny ciąg kończące się spacją lub końcem linii (\s|$).

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

Jedyny problem z tego podejścia jest to, że trzeba nosić na przestrzeni lub wycofanych z linii, który został użyty jako część meczu, stąd enkapsulacji w nawiasach i Wsteczne (\1).

Obudowa jest lepsza dla tego konkretnego pytania, ponieważ nie masz specjalnych wyjątków. Jeśli jednak masz wyjątki, lepiej użyć bardziej jawnej metody. Im więcej narzędzi w zestawie narzędzi, tym lepiej.

+0

lub przecinek, kropka lub średnik itp. – eddi

+0

@eddi Tak, musisz być jednoznaczny. Istnieją zarówno plusy, jak i minusy, aby być wyraźnymi. To stara elastyczność i szybkość kompromisu. – Dinre