我正在尝试确定一个大写姓的方法,但是,不包括小写前缀。
名称及其转换的例子:
还有一些名称将包含需要完全大写的姓氏,因此一个识别前缀(如strchr())的简单函数是不够的:
mb_strtoupper()函数是不合适的,因为它大写了整个字符串。类似地,strtoupper()是不合适的,并且在重音名称上也会失去重音。
有一些答案可以部分回答这个问题,例如:使用PHP的大写,但是,常见的缺陷是假设所有姓为Mac的名字后面都跟着一个大写字母。
名称在数据库中被正确大写,因此我们可以假设拼写为Macarthur的名称是正确的,或者MacArthur对于其他人是正确的。
发布于 2017-01-20 15:54:25
按照规则,在上一封大写字母之后,所有东西都要资本化。
preg_replace_callback('/\p{Lu}\p{Ll}+$/u',
function ($m) { return mb_strtoupper($m[0]); },
$name)\p{Lu}和\p{Ll}分别是Unicode大写字符和小写字符,mb_strtoupper是unicode感知的…。对于一个仅适用于ASCII的简单变体,也可以这样做:
preg_replace_callback('/[A-Z][a-z]+$/',
function ($m) { return strtoupper($m[0]); },
$name)发布于 2017-10-23 20:47:37
下面是一个基本的算法,它可以避免神秘的正则表达式:
以代码形式:
<?php
$names = [
'MacArthur',
'McDavid',
'LeBlanc',
'McIntyre',
'de Wit',
'Macmaster',
'Macintosh',
'MacMac',
'die Über',
'Van der Beek',
'johnson',
'Lindström',
'Cehlárik',
];
// Uppercase after the last capital letter
function normalizeSurname($name) {
// Split surname into a Unicode character array
$chars = preg_split('//u', $name, -1, PREG_SPLIT_NO_EMPTY);
// Capitalize surname and split into a character array
$name_upper = mb_convert_case($name, MB_CASE_UPPER);
$chars_upper = preg_split('//u', $name_upper, -1, PREG_SPLIT_NO_EMPTY);
// Find the index of the last capitalize letter
@$last_capital_idx = array_slice(array_keys(array_intersect($chars, $chars_upper)), -1)[0] ?: 0;
// Concatenate the literal surname up to the index, and capitalized surname thereafter
return mb_substr($name, 0, $last_capital_idx) . mb_substr($name_upper, $last_capital_idx);
}
// Loop through the surnames and display in normalized form
foreach($names as $name) {
echo sprintf("%s -> %s\n",
$name,
normalizeSurname($name)
);
}您将得到如下输出:
MacArthur -> MacARTHUR
McDavid -> McDAVID
LeBlanc -> LeBLANC
McIntyre -> McINTYRE
de Wit -> de WIT
Macmaster -> MACMASTER
Macintosh -> MACINTOSH
MacMac -> MacMAC
die Über -> die ÜBER
Van der Beek -> Van der BEEK
johnson -> JOHNSON
Lindström -> LINDSTRÖM
Cehlárik -> CEHLÁRIK这就产生了这样的假设:一个完全小写的姓氏应该大写。改变这种行为是很容易的。
发布于 2017-01-20 15:44:08
我相信这是解决问题的办法:
$names = array(
'MacArthur',
'Macarthur',
'ÜtaTest',
'de Wit'
);
$pattern = '~(?<prefix>(?:\p{Lu}.+|.+\s+))(?<suffix>\p{Lu}.*)~';
foreach ($names as $key => $name) {
if (preg_match($pattern, $name, $matches)) {
$names[$key] = $matches['prefix'] . mb_strtoupper($matches['suffix']);
} else {
$names[$key] = mb_strtoupper($name);
}
}
print_r($names);它为上面的输入数组产生以下结果:
Array
(
[0] => MacARTHUR
[1] => MACARTHUR
[2] => ÜtaTEST
[3] => de WIT
)正则表达式的简要说明:
(?<prefix> # name of the captured group
(?: # ignore this group
\p{Lu}.+ # any uppercase character followed by any character
| # OR
.+\s+ # any character followed by white space
)
)
(?<suffix> # name of the captured group
\p{Lu}.* # any uppercase character followed by any character
)https://stackoverflow.com/questions/41767011
复制相似问题