小写某些词R

时间:2017-04-03 06:50:11

标签: r regex

我需要将某些单词转换为小写。我正在处理电影片名列表,如果它们不是标题中的第一个单词,那么介词和文章通常是小写的。如果我有矢量:

movies = c('The Kings Of Summer', 'The Words', 'Out Of The Furnace', 'Me And Earl And The Dying Girl')

我需要的是:

movies_updated = c('The Kings of Summer', 'The Words', 'Out of the Furnace', 'Me and Earl and the Dying Girl')

如果不使用gsub()的长序列,是否有一种优雅的方法可以做到这一点,如:

movies_updated = gsub(' In ', ' in ', movies)
movies_updated = gsub(' In', ' in', movies_updated)
movies_updated = gsub(' Of ', ' of ', movies)
movies_updated = gsub(' Of', ' of', movies_updated)
movies_updated = gsub(' The ', ' the ', movies)
movies_updated = gsub(' the', ' the', movies_updated)

等等。

3 个答案:

答案 0 :(得分:9)

实际上,您似乎有兴趣将文字转换为title case。使用stringi包可以很容易地实现这一点,如下所示:

>> stringi::stri_trans_totitle(c('The Kings of Summer', 'The Words', 'Out of the Furnace'))
[1] "The Kings Of Summer" "The Words"           "Out Of The Furnace"

替代方法将涉及使用tools包中提供的toTitleCase函数:

>> tools::toTitleCase(c('The Kings of Summer', 'The Words', 'Out of the Furnace'))
[1] "The Kings of Summer" "The Words"           "Out of the Furnace" 

答案 1 :(得分:8)

虽然我喜欢@ Konrad的简洁回答,但我会提供一个更加文字和手册的替代方案。

movies = c('The Kings Of Summer', 'The Words', 'Out Of The Furnace',
           'Me And Earl And The Dying Girl')

gr <- gregexpr("(?<!^)\\b(of|in|the)\\b", movies, ignore.case = TRUE, perl = TRUE)
mat <- regmatches(movies, gr)
regmatches(movies, gr) <- lapply(mat, tolower)
movies
# [1] "The Kings of Summer"            "The Words"                     
# [3] "Out of the Furnace"             "Me And Earl And the Dying Girl"

正则表达式的技巧:

  • (?<!^)确保我们不会在字符串开头匹配单词。如果没有这个,电影1和2中的第一个The将被缩小。
  • \\b设置了字边界,因此in中间的Dying将不匹配。这比使用空格稍微强一些,因为连字符,逗号等不是空格,而是表示单词的开头/结尾。
  • (of|in|the)匹配ofinthe中的任何一个。可以使用分隔管|添加更多模式。

一旦确定,就像用羽绒版本替换它们一样简单。

答案 2 :(得分:3)

如何使用gsub(使用PCRE正则表达式)将某些 单词转换为小写的另一个示例:

movies = c('The Kings Of Summer', 'The Words', 'Out Of The Furnace', 'Me And Earl And The Dying Girl')
gsub("(?!^)\\b(Of|In|The)\\b", "\\L\\1", movies, perl=TRUE)

请参阅R demo

<强>详情:

  • (?!^) - 不在字符串的开头(如果我们在这里使用前瞻或后观并不重要,因为里面的模式是零宽度断言)
  • \\b - 找到领先word boundary
  • (Of|In|The) - 将OfInThe捕获到第1组
  • \\b - 确保有一个尾随字边界。

替换包含小型运算符\L,它将第一个反向引用值(捕获到第1组中的文本)中的所有字符转换为小写。

请注意,与使用tools::toTitleCase相比,它可以提供更灵活的方法。将特定单词保持为小写的代码部分是:

## These should be lower case except at the beginning (and after :)
lpat <- "^(a|an|and|are|as|at|be|but|by|en|for|if|in|is|nor|not|of|on|or|per|so|the|to|v[.]?|via|vs[.]?|from|into|than|that|with)$"

如果您只需要应用小写而不关心函数中的其他逻辑,那么将这些替代(不要使用^$锚)添加到正则表达式可能就足够了在帖子的顶部。