2013-04-03 11 views
7

Mam wektor ciągów małymi literami. Chciałbym zmienić je na tytułowe, co oznacza, że ​​pierwsza litera każdego słowa będzie pisana wielką literą. Udało mi się to zrobić za pomocą podwójnej pętli, ale mam nadzieję, że jest to bardziej wydajny i elegancki sposób, może jeden liniowiec z gsub i regex.Jak przekonwertować wektor ciągów do tytułu tytułowego

Oto niektóre przykładowe dane, wraz z działającą podwójną pętlą, a następnie inne rzeczy, które wypróbowałem, które nie działały.

To zadziałało, ale wydaje się niezmiernie skomplikowane. Uciekłem do tego dopiero po bezskutecznym eksperymentowaniu z prostszymi podejściami. Oto niektóre z rzeczy, próbowałem, wraz z wyjściem:

# Google search suggested \\U might work, but evidently not in R 
gsub("(\\b[a-z]+)", "\\U\\1" ,strings) 
[1] "Ufirst Uphrase"    "Uanother Uphrase Uto Uconvert" 
[3] "Uand Uhere'Us Uanother Uone" "Ulast-Uone"     

# I tried this on a lark, but to no avail 
gsub("(\\b[a-z]+)", toupper("\\1"), strings) 
[1] "first phrase"    "another phrase to convert" 
[3] "and here's another one" "last-one" 

regex rejestruje odpowiednie pozycje w każdej struny, jak pokazano przez wywołanie gregexpr, ale ciąg wymiana wyraźnie nie działa zgodnie z oczekiwaniami.

Jeśli nie możesz już powiedzieć, jestem stosunkowo nowy w wyliczeniach i byłbym wdzięczny za pomoc w uzyskaniu prawidłowego działania zamiennika. Chciałbym również nauczyć się struktury regex, aby uniknąć przechwytywania listu po apostrofu, ponieważ nie chcę zmieniać przypadku tych liter.

Odpowiedz

18

Głównym problemem jest to, że brakuje Ci perl=TRUE (a twoje wyrażenie jest nieco błędne, chociaż może to być wynikiem wymachiwania, aby spróbować naprawić pierwszy problem).

Korzystanie [:lower:] zamiast [a-z] jest nieco bezpieczniejsze w przypadku kodu kończy się uruchomić w jakimś dziwnym (sorry, Estonians) lokalizacji gdzie z nie jest to ostatnia litera alfabetu ...

re_from <- "\\b([[:lower:]])([[:lower:]]+)" 
strings <- c("first phrase", "another phrase to convert", 
      "and here's another one", "last-one") 
gsub(re_from, "\\U\\1\\L\\2" ,strings, perl=TRUE) 
## [1] "First Phrase"    "Another Phrase To Convert" 
## [3] "And Here's Another One" "Last-One"  

Może wolisz używać \\E (stop kapitalizacji) zamiast \\L (start małe litery), w zależności od tego, co rządzi chcesz śledzić, np:

string2 <- "using AIC for model selection" 
gsub(re_from, "\\U\\1\\E\\2" ,string2, perl=TRUE) 
## [1] "Using AIC For Model Selection" 
+0

Hi @BenBolker, twój re_from powinien być '" \\ b ([[: alpha:]]) ([[: alpha:]] +) "' zamiast '" \\ b ([[: lower:]]) ([[: lower:]] +) "'. W przeciwnym razie nie ma potrzeby używania '\\ E' w twojej ostatniej uwadze. –

7

Bez pomocy regex, strona pomocy dla tolower ma dwie przykładowe funkcje, które to wykonają.

Im bardziej wytrzymała wersja jest

capwords <- function(s, strict = FALSE) { 
    cap <- function(s) paste(toupper(substring(s, 1, 1)), 
        {s <- substring(s, 2); if(strict) tolower(s) else s}, 
          sep = "", collapse = " ") 
    sapply(strsplit(s, split = " "), cap, USE.NAMES = !is.null(names(s))) 
} 
capwords(c("using AIC for model selection")) 
## -> [1] "Using AIC For Model Selection" 

Aby uzyskać podejście regex (prawie) pracy trzeba ustawić `perl = true)

gsub("(\\b[a-z]{1})", "\\U\\1" ,strings, perl=TRUE) 


[1] "First Phrase"    "Another Phrase To Convert" 
[3] "And Here'S Another One" "Last-One" 

ale trzeba będzie radzić sobie z apostrofami nieznacznie lepiej prawdopodobnie

Szybkie wyszukiwanie SO znalezionego https://stackoverflow.com/a/6365349/1385941

+0

Niestety, moje nie tak szybkie wyszukiwanie SO nie spowodowało pojawienia się pytania, które wymieniłeś. Próbowałem "Konwertuj ciąg znaków na tytuł", "konwertuj pierwszą literę każdego słowa na wielką literę", "wielką literę każdego słowa" itd., Ale jakoś nie trafiłem na magiczny ciąg wyszukiwania. W każdym razie, cieszę się, że mam odpowiedzi na moje pytania, ponieważ dodają kilka dodatkowych opcji i dodatkowy wgląd w to, jak działają wyrażenia regularne. – eipi10

6

Już teraz doskonałe odpowiedzi tutaj. Oto jeden wygodę korzystania z funkcji z pakietu raportów:

strings <- c("first phrase", "another phrase to convert", 
    "and here's another one", "last-one") 

CA(strings) 

## > CA(strings) 
## [1] "First Phrase"    "Another Phrase To Convert" 
## [3] "And Here's Another One" "Last-one"  

Choć nie wykorzystać jeden, ponieważ nie ma sensu, aby to zrobić dla moich celów.

Aktualizacja Zarządzam qdapRegex pakiet, który ma TC (tytuł przypadek) funkcję, która robi prawdziwą tytułowy przypadek:

TC(strings) 

## [[1]] 
## [1] "First Phrase" 
## 
## [[2]] 
## [1] "Another Phrase to Convert" 
## 
## [[3]] 
## [1] "And Here's Another One" 
## 
## [[4]] 
## [1] "Last-One" 
4

dorzucę jeszcze jeden do mieszanki dla zabawy:

topropper(strings) 
[1] "First Phrase"    "Another Phrase To Convert" "And Here's Another One" 
[4] "Last-one" 

topropper <- function(x) { 
    # Makes Proper Capitalization out of a string or collection of strings. 
    sapply(x, function(strn) 
    { s <- strsplit(strn, "\\s")[[1]] 
     paste0(toupper(substring(s, 1,1)), 
      tolower(substring(s, 2)), 
      collapse=" ")}, USE.NAMES=FALSE) 
} 
Powiązane problemy