【问题标题】:Lower Case Certain Words R小写某些单词 R
【发布时间】:2017-04-03 06:50:11
【问题描述】:

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

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)

等等。

【问题讨论】:

    标签: r regex


    【解决方案1】:

    实际上,您似乎有兴趣将您的文本转换为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" 
    

    【讨论】:

    • 有趣的是,tools 的答案对我有用,但 stringi 没有。当我将stringi::stri_trans_totitle(c('The Kings of Summer', 'The Words', 'Out of the Furnace')) 粘贴到命令提示符中时,它会产生[1] "The Kings Of Summer" "The Words" [3] "Out Of The Furnace"
    • @andoni34:因为基于 ICU 的 totitle 所做的是将每个单词或句子的首字母大写。来自tools 包的toTitleCase 是一种“黑匣子”,参见its description here
    【解决方案2】:

    虽然我喜欢@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"
    

    正则表达式的技巧:

    • (?&lt;!^) 确保我们不匹配字符串开头的单词。如果没有这个,电影 1 和 2 的第一个 The 将被小写。
    • \\b 设置字边界,这样Dying 中间的in 将不匹配。这比您对空格的使用更可靠,因为连字符、逗号等不是空格,而是表示单词的开头/结尾。
    • (of|in|the) 匹配 ofinthe 中的任何一个。更多图案可以添加分隔管道|

    一旦确定,只需将它们替换为小写版本即可。

    【讨论】:

    • 漂亮,我喜欢这个答案,因为它使用基本 R 并允许灵活地选择哪些单词要小写。这可以在各种不同的情况下工作。非常感谢。
    【解决方案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)$"
    

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

    【讨论】:

    • 我知道它存在,但正在尝试使用小写 \\l,感谢您让我理顺。如果我花更多时间在 perl 特定的大小写更改步骤上,这就是我的答案应该
    • 是的,\l 只会将替换值的 first 字符(紧邻它)转为小写。
    • 这说明了很多 :-)
    猜你喜欢
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多