我需要将某些单词转换为小写。我正在处理电影片名列表,如果它们不是标题中的第一个单词,那么介词和文章通常是小写的。如果我有矢量:
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)
等等。
答案 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)
匹配of
,in
或the
中的任何一个。可以使用分隔管|
添加更多模式。一旦确定,就像用羽绒版本替换它们一样简单。
答案 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)
- 将Of
或In
或The
捕获到第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)$"
如果您只需要应用小写而不关心函数中的其他逻辑,那么将这些替代(不要使用^
和$
锚)添加到正则表达式可能就足够了在帖子的顶部。