我坚持使用NAME字段,通常采用以下格式:
FirstName LastName
Run Code Online (Sandbox Code Playgroud)
但是,我也偶尔会出现以下任何格式的名称(带前缀或后缀):
Mr. First Last
First Last Jr.
Run Code Online (Sandbox Code Playgroud)
人们认为在PHP中将这些变量分割为FIRST/LAST名称变量的安全方法是什么?我无法想出任何一直在工作的东西......
Fra*_*wis 22
正则表达式是处理这类事情的最佳方式.试试这件 - 它会拉出前缀,名字,姓氏和后缀:
$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);
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
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
)
Run Code Online (Sandbox Code Playgroud)
等等…
所以在数组中
$array[0]包含整个字符串.$array[2]始终是名字,$array[3]始终是姓氏.
$array[1]是前缀,$array[4](并不总是设置)是后缀.我还添加了代码来处理像Shaqueal O'neal和D'angelo Hall这样的名字.
Sti*_*ing 17
接受的答案不适用于英语以外的语言或"Oscar de la Hoya"等名称.
这是我所做的一些我认为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;
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
}
Run Code Online (Sandbox Code Playgroud)
你找不到一种安全的方法来解决这个问题,即使是人类总能分辨哪些部分属于名字,哪些部分属于姓氏,特别是当其中一个部分包含几个单词时:Andrea Frank Gutenberg.中间部分弗兰克可以是第二个名字或姓氏为古腾堡的姓氏.
您可以做的最好的事情是,为firstname和lastname提供不同的输入字段,并在数据库中将它们分开安全,这样就可以避免很多问题.