如何将一个字符串向量转换为标题大小写

13

我有一个字符串向量,里面的字符串都是小写的。我想将它们转换为标题大小写,也就是每个单词的首字母都大写。我已经用双重循环实现了这个功能,但我希望有一种更有效和优雅的方法,也许可以用 gsub 和正则表达式来写成一行。

下面是一些示例数据,以及可行的双重循环,以及其他我试过但不起作用的方法。

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

# For each string in the strings vector, find the position of each 
#  instance of a space followed by a letter
matches = gregexpr("\\b[a-z]+", strings) 

# For each string in the strings vector, convert the first letter 
#  of each word to upper case
for (i in 1:length(strings)) {

  # Extract the position of each regex match for the string in row i
  #  of the strings vector.
  match.positions = matches[[i]][1:length(matches[[i]])] 

  # Convert the letter in each match position to upper case
  for (j in 1:length(match.positions)) {

    substr(strings[i], match.positions[j], match.positions[j]) = 
      toupper(substr(strings[i], match.positions[j], match.positions[j]))
  }
}

这样可以解决问题,但似乎过于复杂。在尝试了更为简单直接的方法失败后才采用了它。下面是我尝试过的一些方法以及输出:

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

正则表达式通过调用gregexpr显示捕获了每个字符串中的正确位置,但是替换字符串明显没有按预期工作。

如果您还没有意识到,我对正则表达式相对较新,并希望得到有关如何使替换正确工作的帮助。我也想学习如何设置正则表达式以避免在撇号后捕获字母,因为我不希望更改这些字母的大小写。

6个回答

24
主要问题是你缺少了perl=TRUE(而且你的正则表达式略有问题,虽然这可能是为了解决第一个问题而挣扎)。
在代码最终运行在某些奇怪的( 对不起,爱沙尼亚人)区域设置中字母z不是字母表中的最后一个字母时,使用[:lower:]代替[a-z](或[:alpha:]代替[A-Za-z])稍微更安全一些...
re_from <- "\\b([[:alpha:]])([[:alpha:]]+)"
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"    

您可能更喜欢使用\\E(停止大写)而不是\\L(开始小写),这取决于您想遵循的规则,例如:

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

1
嗨@BenBolker,你的re_from应该是"\b([[:alpha:]])([[:alpha:]]+)"而不是"\b([[:lower:]])([[:lower:]]+)"。否则,在你最后的评论中使用\\E就没有意义了。 - green diod

8

在不使用 regex 的情况下,tolower 的帮助页面有两个示例函数可以实现此功能。

更健壮的版本是

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"

为了让你的正则表达式方法(几乎)起作用,你需要设置 `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"  

但或许你需要更好地处理撇号。

sapply(lapply(strsplit(strings, ' '), gsub, pattern = '^([[:alnum:]]{1})', replace = '\\U\\1', perl = TRUE), paste,collapse = ' ')

快速搜索 SO 找到了 https://dev59.com/FWw15IYBdhLWcg3w1vWB#6365349


很遗憾,我在 Stack Overflow 上并没有找到你提到的问题。我尝试了“将字符串转换为标题大小写”、“将每个单词的首字母转换为大写”、“将每个单词的首字母大写”,等等,但不知何故没有找到正确的搜索关键词。无论如何,我很高兴得到了我的问题的答案,因为它们增加了一些选项,并对正则表达式的工作原理提供了一些额外的见解。 - eipi10

6

这里已经有很好的答案了。以下是使用reports包中的便捷函数的示例:

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"       

尽管它不会将一个词首字母大写,因为在我的情况下这样做没有意义。

更新我管理的 qdapRegex 包具有执行真正标题大小写的 TC (标题大小写)函数:

TC(strings)

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

4
我为了好玩再增加一个:
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)
}

3

以下是另一个基于stringr包的一行代码:

str_to_title(strings, locale = "en")

其中strings是您的字符串向量。

来源


0

将任何大小写转换为其他大小写的最佳方法是在R中使用snakecase包。

只需使用该软件包即可。

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

to_title_case(strings)

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

继续编程!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接