Lab: Clean Messy Phone Numbers
คุณได้รับ list เบอร์โทรนักเรียน 8 คน ที่กรอกมาคนละรูปแบบ — งานของคุณคือทำให้ทุกเบอร์เป็นรูปแบบเดียวกัน:
0812345678(10 หลัก เริ่มด้วย 0)
เวลาที่ใช้: ~20 นาที
ข้อมูล
Section titled “ข้อมูล”| student_id | name | phone_raw |
|---|---|---|
| 001 | Ploy | 081-234-5678 |
| 002 | Som | +66812345678 |
| 003 | Tong | 081 234 5678 |
| 004 | Fah | 0898765432 |
| 005 | Bank | +66 89 876 5432 |
| 006 | Mint | 812345678 |
| 007 | Pim | 085-678-1234 |
| 008 | Ice | +6685 678 1234 |
ปัญหาที่พบ:
- มี
-(dash) ขั้น - มี spaces ขั้น
- บางเบอร์ใช้
+66แทน0นำหน้า - บางเบอร์ไม่มี
0นำหน้า (Mint:812345678)
Output ที่ต้องการ: ทุกเบอร์เป็น format 0XXXXXXXXX (10 หลัก)
คำสั่ง
Section titled “คำสั่ง”-
สร้างข้อมูลในแต่ละเครื่องมือ (ดู tab ด้านล่าง)
-
เขียน formula/code ที่:
- ลบ spaces และ dashes ออก
- แปลง
+66เป็น0 - เติม
0นำหน้าถ้าเบอร์มี 9 หลัก - ตรวจสอบว่าผลลัพธ์มี 10 หลักพอดี
-
ตรวจสอบว่าทุกเครื่องมือให้ผลลัพธ์เดียวกัน
สร้าง sheet ใหม่ ใส่ข้อมูลใน column A-C แล้วเขียนสูตรใน column D:
วิธีคิด (ทำทีละขั้น):
ขั้นที่ 1: ลบ spaces → =SUBSTITUTE(C2," ","")
ขั้นที่ 2: ลบ dashes → =SUBSTITUTE(SUBSTITUTE(C2," ",""),"-","")
ขั้นที่ 3: แปลง +66 → 0 → =SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(C2," ",""),"-",""),"+66","0")
ขั้นที่ 4: เติม 0 ถ้ามี 9 หลัก → ใช้ IF + LEN
รวมทุกขั้น:
=IF(LEN(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(C2," ",""),"-",""),"+66","0"))=9, "0"&SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(C2," ",""),"-",""),"+66","0"), SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(C2," ",""),"-",""),"+66","0"))Hint: ใช้ helper column ทำทีละขั้นจะง่ายกว่าเขียนสูตรเดียวยาวๆ
สำคัญ: format column D เป็น “Plain text” ก่อน ไม่งั้น 0812345678 จะกลายเป็น 812345678!
#include <stdio.h>#include <string.h>#include <ctype.h>
// ฟังก์ชัน clean เบอร์โทรvoid clean_phone(const char *raw, char *result) { char temp[50] = ""; int j = 0;
// ขั้น 1: ลบ spaces และ dashes for (int i = 0; raw[i] != '\0'; i++) { if (raw[i] != ' ' && raw[i] != '-') { temp[j++] = raw[i]; } } temp[j] = '\0';
// ขั้น 2: แปลง +66 เป็น 0 if (strncmp(temp, "+66", 3) == 0) { result[0] = '0'; strcpy(result + 1, temp + 3); } // ขั้น 3: เติม 0 ถ้ามี 9 หลัก else if (strlen(temp) == 9 && temp[0] != '0') { result[0] = '0'; strcpy(result + 1, temp); } else { strcpy(result, temp); }}
int main() { char *phones[] = { "081-234-5678", "+66812345678", "081 234 5678", "0898765432", "+66 89 876 5432", "812345678", "085-678-1234", "+6685 678 1234" }; char *names[] = {"Ploy","Som","Tong","Fah","Bank","Mint","Pim","Ice"};
for (int i = 0; i < 8; i++) { char cleaned[20]; clean_phone(phones[i], cleaned); printf("%-5s: %-20s → %s (len=%zu)\n", names[i], phones[i], cleaned, strlen(cleaned)); }
return 0;}ลองรัน แล้วดูว่าทุกเบอร์ออกมา 10 หลักเริ่มด้วย 0 ไหม
import pandas as pd
df = pd.DataFrame({ 'student_id': ['001','002','003','004','005','006','007','008'], 'name': ['Ploy','Som','Tong','Fah','Bank','Mint','Pim','Ice'], 'phone_raw': [ '081-234-5678', '+66812345678', '081 234 5678', '0898765432', '+66 89 876 5432', '812345678', '085-678-1234', '+6685 678 1234' ]})
# วิธีที่ 1: ทีละขั้น (อ่านง่าย)cleaned = (df['phone_raw'] .str.replace(' ', '', regex=False) # ลบ spaces .str.replace('-', '', regex=False) # ลบ dashes .str.replace('+66', '0', regex=False) # +66 → 0)# เติม 0 ถ้ามี 9 หลักcleaned = cleaned.apply(lambda x: '0' + x if len(x) == 9 else x)
df['phone_clean'] = cleanedprint(df[['name', 'phone_raw', 'phone_clean']])
# ตรวจสอบprint(f"\nทุกเบอร์มี 10 หลัก: {(df['phone_clean'].str.len() == 10).all()}")print(f"ทุกเบอร์เริ่มด้วย 0: {(df['phone_clean'].str[0] == '0').all()}")ลองเพิ่ม:
# วิธีที่ 2: ใช้ regex (สั้นกว่า)import re
def clean_phone(raw): digits = re.sub(r'[^\d+]', '', raw) # เหลือแค่ตัวเลขและ + digits = re.sub(r'^\+66', '0', digits) # +66 → 0 if len(digits) == 9 and not digits.startswith('0'): digits = '0' + digits return digits
df['phone_regex'] = df['phone_raw'].apply(clean_phone)print(df[['name', 'phone_clean', 'phone_regex']])# ตรวจว่าทั้ง 2 วิธีให้ผลเหมือนกันprint(f"ผลตรงกัน: {(df['phone_clean'] == df['phone_regex']).all()}")CREATE TABLE students_raw ( student_id VARCHAR(3), name VARCHAR(50), phone_raw VARCHAR(30));
INSERT INTO students_raw VALUES ('001','Ploy','081-234-5678');INSERT INTO students_raw VALUES ('002','Som','+66812345678');INSERT INTO students_raw VALUES ('003','Tong','081 234 5678');INSERT INTO students_raw VALUES ('004','Fah','0898765432');INSERT INTO students_raw VALUES ('005','Bank','+66 89 876 5432');INSERT INTO students_raw VALUES ('006','Mint','812345678');INSERT INTO students_raw VALUES ('007','Pim','085-678-1234');INSERT INTO students_raw VALUES ('008','Ice','+6685 678 1234');
-- ทำความสะอาดทีละขั้นSELECT name, phone_raw,
-- ขั้น 1: ลบ spaces และ dashes REPLACE(REPLACE(phone_raw, ' ', ''), '-', '') AS step1_no_spaces,
-- ขั้น 2: แปลง +66 → 0 REPLACE(REPLACE(REPLACE(phone_raw, ' ', ''), '-', ''), '+66', '0') AS step2_no_plus66,
-- ขั้น 3: เติม 0 ถ้า 9 หลัก CASE WHEN LENGTH(REPLACE(REPLACE(REPLACE(phone_raw, ' ', ''), '-', ''), '+66', '0')) = 9 THEN '0' || REPLACE(REPLACE(REPLACE(phone_raw, ' ', ''), '-', ''), '+66', '0') ELSE REPLACE(REPLACE(REPLACE(phone_raw, ' ', ''), '-', ''), '+66', '0') END AS phone_clean
FROM students_raw;
-- ตรวจสอบSELECT name, phone_clean, LENGTH(phone_clean) AS lenFROM ( SELECT name, CASE WHEN LENGTH(REPLACE(REPLACE(REPLACE(phone_raw,' ',''),'-',''),'+66','0')) = 9 THEN '0' || REPLACE(REPLACE(REPLACE(phone_raw,' ',''),'-',''),'+66','0') ELSE REPLACE(REPLACE(REPLACE(phone_raw,' ',''),'-',''),'+66','0') END AS phone_clean FROM students_raw) t;-- ทุกแถวต้องได้ len = 10สำคัญ: phone_clean ต้องเป็น VARCHAR ไม่ใช่ INTEGER — ไม่งั้น 0 นำหน้าจะหาย!
ดูเฉลย
ผลลัพธ์ที่ถูกต้อง (ทุกเครื่องมือต้องได้เหมือนกัน):
| name | phone_raw | phone_clean |
|---|---|---|
| Ploy | 081-234-5678 | 0812345678 |
| Som | +66812345678 | 0812345678 |
| Tong | 081 234 5678 | 0812345678 |
| Fah | 0898765432 | 0898765432 |
| Bank | +66 89 876 5432 | 0898765432 |
| Mint | 812345678 | 0812345678 |
| Pim | 085-678-1234 | 0856781234 |
| Ice | +6685 678 1234 | 0856781234 |
ขั้นตอนการทำงาน:
- ลบ spaces และ dashes — ทุกเครื่องมือมี REPLACE/substitute
- แปลง +66 → 0 — ทุกเครื่องมือมี REPLACE/substitute
- เติม 0 ถ้า 9 หลัก — ต้องเช็คความยาวก่อน
จุดที่ต้องระวัง:
- Sheets: format column เป็น “Plain text” ก่อน ไม่งั้น
0812345678กลายเป็น812345678 - Python: ใช้
regex=Falseใน.str.replace()เพราะ+เป็น special character ใน regex - SQL: ผลลัพธ์ต้องอยู่ใน
VARCHARcolumn ไม่ใช่INTEGER
บทเรียนรวม Module 2:
- เบอร์โทรคือ text ไม่ใช่ตัวเลข (Leading zeros!)
- ข้อมูลจากโลกจริงไม่เคยสะอาด — ต้อง clean เสมอ
- ทุกเครื่องมือมี text operations เหมือนกัน — แค่ syntax ต่างกัน