2012-06-22 14 views
9

Chciałbym zaimplementować funkcję z R, która usuwa powtarzające się znaki w ciągu znaków. Załóżmy, że moja funkcja nosi nazwę removeRS, tak to ma działać w ten sposób:Jak mogę usunąć powtarzające się znaki w ciągu znaków za pomocą R?

removeRS('Buenaaaaaaaaa Suerrrrte') 
    Buena Suerte 
    removeRS('Hoy estoy tristeeeeeee') 
    Hoy estoy triste 

Moja funkcja ma być używana z ciągów pisanych w języku hiszpańskim, więc nie jest to, że często (lub przynajmniej poprawne), aby znaleźć słowa, które mają więcej niż trzy kolejne samogłoski. Nie zawracaj sobie głowy możliwymi uczuciami za nimi. Niemniej jednak istnieją słowa, które mogą mieć dwie kolejne spółgłoski (szczególnie ll i rr), ale możemy pominąć to z naszej funkcji.

Tak więc, podsumowując, ta funkcja powinna zastąpić litery, które pojawiają się co najmniej trzy razy z rzędu z samą literą. W jednym z powyższych przykładów aaaaaaaaa zastąpiono a.

Czy możesz podać mi jakieś wskazówki do wykonania tego zadania z R?

+0

"To zadanie" nie jest obecnie wyraźnie określone. Powtarzające się samogłoski mogą wymagać innego traktowania, ale nie wynika to z opisu. –

Odpowiedz

19

Nie sądziłem, że bardzo uważnie na to, ale to jest moje szybkie rozwiązanie pomocą odwołań w wyrażeniach regularnych :

gsub('([[:alpha:]])\\1+', '\\1', 'Buenaaaaaaaaa Suerrrrte') 
# [1] "Buena Suerte" 

() rejestruje pierwsze pismo, \\1 odnosi się do tego pisma + oznacza dopasować go raz lub więcej; ułóż wszystkie te elementy razem, możemy dopasować literę dwa lub więcej razy.

Aby dołączyć inne znaki oprócz znaków alfanumerycznych, należy zastąpić [[:alpha:]] wyrażeniem pasującym do tego, co ma być dołączone.

+1

Dzięki, a jeśli chcesz wykluczyć niektóre litery z tego? Na przykład wyklucz litery L i R. – Nestorghh

+0

'[: alpha:]' oznacza 'a-zA-Z'; jeśli chcesz być konkretny, możesz powiedzieć, np. '[a-zA-KM-QS-Z]', aby usunąć wielkie litery L i R; zobacz '? regexp' –

+0

Oto wariacja używająca wyrażenia zerowego szerokości zerowej wyrażeń regularnych:' gsub ("([[: alpha:]]) (? = \\ 1)", "", s, perl = TRUE) '. Pasuje do wszystkich, z wyjątkiem ostatniego, w każdym przebiegu znaków alfabetu. –

5

Myślę, że powinieneś zwrócić uwagę na niejasności w opisie problemu. Jest to pierwsze ukłucie, ale to wyraźnie nie działa z „Good Luck” w sposób pragnienie:

removeRS <- function(str) paste(rle(strsplit(str, "")[[1]])$values, collapse="") 
removeRS('Buenaaaaaaaaa Suerrrrte') 
#[1] "Buena Suerte" 
+0

Dzięki za odpowiedź @DWin. Przykład z "Good Luck" nie przeszkadza mi wcale i akceptuję i przepraszam za niejasności. Rzeczy w języku angielskim nie działają tak jak w języku hiszpańskim w tym sensie. Wypróbowałem Twoje rozwiązanie i działa tak, jak chcę. Przy okazji, zredagowałem pytanie, aby było bardziej zrozumiałe. – Nestorghh

0

Ponieważ chcesz zastąpić litery, które pojawiają się co najmniej 3 razy, tu jest moje rozwiązanie:

gsub("([[:alpha:]])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
#[1] "Buenna Suertee" 

Jak widać 4 „a” zostały zredukowane do zaledwie 1 a, 3 R mają zostały zredukowane do 1 r, ale 2 n i 2 e nie zostały zmienione. Jak sugerowano powyżej można wymienić [[:alpha:]] dowolnej kombinacji [a-zA-KM-Z] lub podobny, a nawet korzystać z „lub” operator | wewnątrz nawiasów Squre [y|Q] jeśli chcesz, aby Twój kod wpływać tylko powtórzeń y i Q.

gsub("([a|e])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
# [1] "Buenna Suerrrtee" 
# triple r are not affected and there are no triple e. 
Powiązane problemy