Tag Archive lastname

Byphunsanit

แบ่งชื่อ นามสกุล คำนำหน้านาม

โจทย์คือการ import ข้อมูลจาก excel เข้าไปเก็บใน database ซึ่งมันก็ไม่ซับซ้อนอะไรถ้าคำนำหน้านาม, ชื่อ, ชื่อกลาง, นามสกุลมันไม่อยู่ในช่องเดียวกัน แต่ในตารางต้องการให้แยกไว้คนละฟิลย์เพื่อความสะดวกในการดึงข้อมูล

ดูง่ายๆ แค่ตัดสตริงค์ตามช่องว่างก็น่าจะได้ แต่อย่างชื่อผม นาย พิชญ์ พันธุ์สนิท และชื่อ นาง ธิติมา แอน ประทุมทิพย์ ต่างกันคือ ตัดออกมาได้อาร์เรย์สมาชิก 3 ตัว และ 4 ตัว ก็เขียนเงื่อนไขได้ง่ายๆ ถ้ามี 4 ตัวก็แสดงว่ามี ชื่อกลาง

title = นาย
firstname = พิชญ์
middlename =
lastname = พันธุ์สนิท

และ
title = นาง
firstname = ธิติมา
middlename = แอน
lastname = ประทุมทิพย์

เขียน if (count($temp) == 4) ก็ได้แล้ว

แต่อย่าง ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข ถ้าใช้วิธี

list($title, $firstname, $middlename, lastname) = explode(' ', 'ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข')

แล้วออกมาเป็น

title = ว่าที่
firstname = ร.ต.
middlename = (หญิง)
lastname = เต็มศิริ

คงไม่งาม และบางราชชื่อไม่มีคำนำหน้านาม เช่น ( hr ผู้น่ารัก )

โชคดีที่มีคำนำหน้านามไม่เยอะเพราะฉะนั้นใช้วิธีใส่ในอาร์เรย์แล้วเอาไป search หาเอาก็ได้

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>แบ่งชื่อ นามสกุล คำนำหน้านาม</title>
</head>
<body>
<?php
 
$names = [
    'ซาร่า มาลา กุล เลน ณ อยุธยา',
    'นพ.เหรียญทอง แน่นหนา',
    'นักเทคนิคการแพทย์ภาคภูมิ เดชหัสดิน',
    'นางธิติมา แอน ประทุมทิพย์',
    'นายพิชญ์ พันธุ์สนิท',
    'ว่าที่ ร.ต.(หญิง) เต็มศิริ วีรสุข',
];
 
$titles = [
    'นพ.',
    'นักเทคนิคการแพทย์',
    'นาง',
    'นาย',
    'ว่าที่ ร.ต.(หญิง)',
];
 
$results = [];
foreach ($names as $no => $name) {
 
    $temp = str_replace($titles, '<> ', $name);
    $temp = mb_ereg_replace('/\s+/', '\s', $temp);
    $temp = array_values(array_filter(explode(' ', $temp)));
 
    if ($temp[0] == '<>') {
        $results[$no]['title'] = substr($name, 0, strpos($name, $temp[1]));
    } else {
        $results[$no]['title'] = '';
        array_unshift($temp, '');
    }
 
    $results[$no]['firstname'] = $temp[1];
    if (count($temp) == 4) {
        $results[$no]['middlename'] = $temp[2];
        $results[$no]['lastname'] = $temp[3];
    } else {
        unset($temp[0], $temp[1]);
        $results[$no]['middlename'] = '';
        $results[$no]['lastname'] = implode(' ', $temp);
    }
}
 
echo '<pre>', print_r($results, true), '</pre>';
?>
</body>
</html>

ผลลัพธ์ คือ

Array
(
    [0] => Array
        (
            [title] =>
            [firstname] => ซาร่า
            [middlename] =>
            [lastname] => มาลา กุล เลน ณ อยุธยา
        )
 
    [1] => Array
        (
            [title] => นพ.
            [firstname] => เหรียญทอง
            [middlename] =>
            [lastname] => แน่นหนา
        )
 
    [2] => Array
        (
            [title] => นักเทคนิคการแพทย์
            [firstname] => ภาคภูมิ
            [middlename] =>
            [lastname] => เดชหัสดิน
        )
 
    [3] => Array
        (
            [title] => นาง
            [firstname] => ธิติมา
            [middlename] => แอน
            [lastname] => ประทุมทิพย์
        )
 
    [4] => Array
        (
            [title] => นาย
            [firstname] => พิชญ์
            [middlename] =>
            [lastname] => พันธุ์สนิท
        )
 
    [5] => Array
        (
            [title] => ว่าที่ ร.ต.(หญิง)
            [firstname] => เต็มศิริ
            [middlename] =>
            [lastname] => วีรสุข
        )
 
)

อธิบาย

$temp = str_replace($titles, '<> ', $name);

เปลี่ยนคำนำหน้านามเป็นตัวอื่นก่อน

	$temp = mb_ereg_replace('/\s+/', '\s', $temp);

เอาสเปซที่มีมากกว่า 1 ตำแหน่งแทนที่ด้วยช่องว่าแค่ 1 ตำแหน่งก็พอ

$temp = array_values(array_filter(explode(' ', $temp)));

แบ่งข้อมูลออกเป็นส่วนๆ โดย array_values(array_filter()) จะทำให้อินเด็กซ์ของอาร์เรย์เป็นไปตามลำดับ

array_unshift($temp, '');

ถ้าไม่มีคำนำหน้านามก็ใส่ให้มัน ลำดับอาร์เรย์จะได้ไม่เคลื่อนไป

$results[$no]['lastname'] = implode(' ', $temp);

เพราะว่าบางคน นามสกุล จะมีช่องว่างจำนวนมาก เช่น มาลา กุล เลน ณ อยุธยา และถ้าแบ่งข้อมูลผิด ผลลัพธ์ที่ได้ก็ไม่น่าเกลียดเท่าไหร่