将人名大写(占 ' 和 - )
Posted
技术标签:
【中文标题】将人名大写(占 \' 和 - )【英文标题】:Decapitalize human names (accounting for ' and -)将人名大写(占 ' 和 - ) 【发布时间】:2015-12-21 23:52:59 【问题描述】:我有一个(人类)名字的向量,全部大写:
names <- c("FRIEDRICH SCHILLER", "FRANK O'HARA", "HANS-CHRISTIAN ANDERSEN")
到目前为止,为了减少大写(仅首字母大写),我正在使用
simpleDecap <- function(x)
s <- strsplit(x, " ")[[1]]
paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=" ")
sapply(names, simpleDecap, USE.NAMES=FALSE)
# [1] "Friedrich Schiller" "Frank O'hara" "Hans-christian Andersen"
但我也想说明'
和-
。使用s <- strsplit(x, " |\\'|\\-")[[1]]
当然可以找到正确的字母,但随后在折叠'
和-
中迷路了。因此,我尝试了
simpleDecap2 <- function(x)
for (char in c(" ", "\\-", "\\'"))
s <- strsplit(x, char)[[1]]
x <-paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=char)
return x
sapply(names, simpleDecap, USE.NAMES=FALSE)
当然,这更糟糕,因为结果会一个接一个地分开:
sapply(names, simpleDecap2, USE.NAMES=FALSE)
# [1] "Friedrich schiller" "Frank o'Hara" "Hans-christian andersen"
我认为正确的方法是根据s <- strsplit(x, " |\\'|\\-")[[1]]
进行拆分,但paste=
是问题所在。
【问题讨论】:
【参考方案1】:这似乎可行,使用 Perl 兼容的正则表达式:
gsub("\\b(\\w)([\\w]+)", "\\1\\L\\2", names, perl = TRUE)
\L
将以下匹配组转换为小写。
【讨论】:
喜欢 perl-regexp 的简洁性和不可理解性:-) @CarlWitthoft 我真的不同意这一点。像任何其他语言一样,它们必须学习,但就它们表达的内容而言,它们非常简单易懂。正则表达式难以理解的普遍说法是一个巨大的谣言:等效的手动解析代码几乎总是更复杂且更难理解。对此使用“难以理解”这个词确实具有误导性。 这是对 perl 本身允许编程风格的模因的幽默挖掘,相比之下,混淆的 c 代码竞赛显得苍白无力。当然,正则表达式是 进行字符串操作的方式。 偏离了已发布的问题 - 假设有一个类似FRED BOUchARD
的输入,或者更糟的是 IAN MACDONALD
(Ian MacDonald)。
@CarlWitthoft 您的“Fred Bouchard”案例有效(或者这应该对外壳做一些奇怪的事情?)。像“MacDonald”这样的东西如果不硬编码这样的前缀就很难(不可能?)。【参考方案2】:
虽然我同意 Perl 正则表达式是更好的解决方案,但 simpleDecap2
方法离工作并不遥远。
simpleDecap3 <- function(x)
x <- tolower(x)
for (char in c(" ", "-", "'"))
s <- strsplit(x, char)[[1]]
x <-paste0(toupper(substring(s, 1,1)), substring(s, 2), collapse=char)
x
即把整个名称转小写,然后将“”、“-”或“'”后面的第一个字母大写。不像正则表达式那样好看,而且很可能没有那么健壮,但它只需对原始代码进行微小的更改即可完成工作。
【讨论】:
这只返回第一个值。 是的,它和simpleDecap2
的格式一样,你需要像sapply(names, simpleDecap3, USE.NAMES=FALSE)
这样称呼它。以上是关于将人名大写(占 ' 和 - )的主要内容,如果未能解决你的问题,请参考以下文章