我不得不使用NAME字段,它的格式通常是:
FirstName LastName
但是,我偶尔也会有这些格式(带前缀或后缀)的名称:
Mr. First Last
First Last Jr.
人们认为在PHP中将这些变量分成名字/姓氏变量的安全方法是什么?我真的想不出任何东西总是有效的……
发布于 2012-01-10 19:14:44
正则表达式是处理这类事情的最好方法。试试这个--它会提取出前缀、名字、姓氏和后缀:
$array = array(
'FirstName LastName',
'Mr. First Last',
'First Last Jr.',
'Shaqueal O’neal',
'D’angelo Hall',
);
foreach ($array as $name)
{
$results = array();
echo $name;
preg_match('#^(\w+\.)?\s*([\'\’\w]+)\s+([\'\’\w]+)\s*(\w+\.?)?$#', $name, $results);
print_r($results);
}
结果是这样的:
FirstName LastName
Array
(
[0] => FirstName LastName
[1] =>
[2] => FirstName
[3] => LastName
)
Mr. First Last
Array
(
[0] => Mr. First Last
[1] => Mr.
[2] => First
[3] => Last
)
First Last Jr.
Array
(
[0] => First Last Jr.
[1] =>
[2] => First
[3] => Last
[4] => Jr.
)
shaqueal o’neal
Array
(
[0] => shaqueal o’neal
[1] =>
[2] => shaqueal
[3] => o’neal
)
d’angelo hall
Array
(
[0] => d’angelo hall
[1] =>
[2] => d’angelo
[3] => hall
)
etc…
所以在数组中,$array[0]
包含整个字符串。$array[2]
始终是名字,$array[3]
始终是姓氏。$array[1]
是前缀,$array[4]
(并非总是设置)是后缀。我还为像Shaqueal O‘’neal和D‘also这样的名字添加了处理’and‘的代码。
发布于 2013-01-19 23:54:23
被接受的答案不适用于英语以外的语言,也不适用于像“奥斯卡·德拉霍亚”这样的名字。
下面是我所做的一些事情,我认为utf-8是安全的,适用于所有这些情况,建立在公认答案的假设上,即前缀和后缀将有一个句点:
/**
* splits single name string into salutation, first, last, suffix
*
* @param string $name
* @return array
*/
public static function doSplitName($name)
{
$results = array();
$r = explode(' ', $name);
$size = count($r);
//check first for period, assume salutation if so
if (mb_strpos($r[0], '.') === false)
{
$results['salutation'] = '';
$results['first'] = $r[0];
}
else
{
$results['salutation'] = $r[0];
$results['first'] = $r[1];
}
//check last for period, assume suffix if so
if (mb_strpos($r[$size - 1], '.') === false)
{
$results['suffix'] = '';
}
else
{
$results['suffix'] = $r[$size - 1];
}
//combine remains into last
$start = ($results['salutation']) ? 2 : 1;
$end = ($results['suffix']) ? $size - 2 : $size - 1;
$last = '';
for ($i = $start; $i <= $end; $i++)
{
$last .= ' '.$r[$i];
}
$results['last'] = trim($last);
return $results;
}
下面是phpunit测试:
public function testDoSplitName()
{
$array = array(
'FirstName LastName',
'Mr. First Last',
'First Last Jr.',
'Shaqueal O\'neal',
'D’angelo Hall',
'Václav Havel',
'Oscar De La Hoya',
'АБВГҐД ЂЃЕЀЁЄЖЗ', //cyrillic
'דִּיש מַחֲזֹור', //yiddish
);
$assertions = array(
array(
'salutation' => '',
'first' => 'FirstName',
'last' => 'LastName',
'suffix' => ''
),
array(
'salutation' => 'Mr.',
'first' => 'First',
'last' => 'Last',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'First',
'last' => 'Last',
'suffix' => 'Jr.'
),
array(
'salutation' => '',
'first' => 'Shaqueal',
'last' => 'O\'neal',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'D’angelo',
'last' => 'Hall',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'Václav',
'last' => 'Havel',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'Oscar',
'last' => 'De La Hoya',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'АБВГҐД',
'last' => 'ЂЃЕЀЁЄЖЗ',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'דִּיש',
'last' => 'מַחֲזֹור',
'suffix' => ''
),
);
foreach ($array as $key => $name)
{
$result = Customer::doSplitName($name);
$this->assertEquals($assertions[$key], $result);
}
}
发布于 2012-01-10 19:13:02
你不会找到一个安全的方法来解决这个问题,即使是人类也不能总是区分哪些部分属于名字,哪些属于姓氏,特别是当其中一个包含几个单词时,比如: Andrea Frank Gutenberg。中间部分Frank可以是第二个名字,也可以是姓氏和婚前姓Gutenberg。
你能做的最好的事情是,为名字和姓氏提供不同的输入域,并将它们安全地分隔在数据库中,这样你就可以避免很多问题。
https://stackoverflow.com/questions/8808902
复制