0Pricing
Pandas & NumPy Academy · บทเรียน

การจับคู่รูปแบบด้วย Regex

แยกส่วนย่อยของสตริงและตรวจสอบรูปแบบด้วย .str.extract(), .str.contains() และ .str.match() โดยใช้นิพจน์ทั่วไป

การจับคู่รูปแบบด้วย Regex เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงใช้ Regex ใน Pandas

นิพจน์ทั่วไป (regex) คือภาษาสำหรับอธิบายรูปแบบของสตริง ใน Pandas ตัวเข้าถึง .str เปิดให้ใช้ regex ผ่าน contains(), match(), extract(), findall() และ replace() Regex เป็นเครื่องมือที่เหมาะสมเมื่อรูปแบบของคุณซับซ้อนเกินกว่าจะใช้การตรวจสอบ contains/startswith แบบง่าย ๆ เช่น ตรวจสอบรูปแบบอีเมล แยกหมายเลขโทรศัพท์จากข้อความอิสระ หรือค้นหาจำนวนเงินทั้งหมดในคอลัมน์บันทึก

import pandas as pd

df = pd.DataFrame({
    'text': ['Order #12345 placed', 'No order', 'Ref #67890 paid', 'Refund for #11111']
})

# Find rows that contain an order number (# followed by 5 digits)
has_order = df['text'].str.contains(r'#\d{5}', regex=True)
print(df[has_order])
#                  text
# 0  Order #12345 placed
# 2    Ref #67890 paid
# 3  Refund for #11111

ใช้ .str.contains() ร่วมกับ Regex

.str.contains(pattern) เมื่อใช้กับ regex=True (ค่าเริ่มต้น) จะส่งคืน Series แบบบูลีนที่มีค่า True ในตำแหน่งที่รูปแบบตรงกับส่วนใดก็ตามของสตริง ใช้จุดยึด เช่น ^ (จุดเริ่มต้น) และ $ (จุดสิ้นสุด) เพื่อจำกัดตำแหน่งที่จับคู่ การใช้งานที่พบบ่อยคือกรองแถวที่ฟิลด์ตรงตามข้อกำหนดรูปแบบ เช่น รูปแบบวันที่ที่ถูกต้องหรือรหัสที่จัดรูปแบบอย่างเหมาะสม

import pandas as pd

df = pd.DataFrame({
    'code': ['US-001', 'UK-042', 'DE-18', 'FR-', 'us-003']
})

# Valid format: two uppercase letters, hyphen, 3 digits
valid = df['code'].str.contains(r'^[A-Z]{2}-\d{3}$', regex=True)
print(df['code'][valid].tolist())
# ['US-001', 'UK-042']

.str.match() สำหรับการจับคู่ที่มีจุดยึด

.str.match(pattern) ตรวจสอบว่าแต่ละสตริงขึ้นต้นด้วยรูปแบบหรือไม่ (รูปแบบจะถูกยึดไว้ที่จุดเริ่มต้น) นี่คือความแตกต่างจาก contains() ซึ่งค้นหาทั่วทั้งสตริง ใช้ match() เมื่อสนใจเฉพาะคำนำหน้าของสตริง และใช้ fullmatch() เมื่อทั้งสตริงต้องตรงกับรูปแบบ

import pandas as pd

df = pd.DataFrame({'id': ['ORD001', 'ORD002', 'RET003', 'ORDXYZ']})

# Match rows whose ID starts with 'ORD' followed by digits
orders = df['id'].str.match(r'ORD\d+')
print(df[orders])
#        id
# 0  ORD001
# 1  ORD002

# match() is anchored at start, so 'ORDXYZ' (XYZ not digits) is excluded

ใช้ .str.extract() สำหรับกลุ่มที่จับ

.str.extract(pattern) ใช้กลุ่มที่จับ () ในรูปแบบ regex เพื่อดึงส่วนที่ต้องการจากสตริงที่ตรงกัน โดยส่งคืน DataFrame ที่มีหนึ่งคอลัมน์ต่อหนึ่งกลุ่มที่จับ ระบบจะส่งคืนเฉพาะการตรงกันครั้งแรกในแต่ละสตริง วิธีนี้เหมาะอย่างยิ่งสำหรับการแยกข้อมูลที่มีโครงสร้างซึ่งฝังอยู่ในข้อความอิสระ เช่น ค่าตัวเลข วันที่ หรือรหัสประจำตัว

import pandas as pd

df = pd.DataFrame({
    'notes': ['Shipped on 2024-01-15', 'Delivered on 2024-03-20', 'Pending', 'Shipped on 2024-07-04']
})

# Extract the date (YYYY-MM-DD) from the notes column
dates = df['notes'].str.extract(r'(\d{4}-\d{2}-\d{2})')
df['shipped_date'] = dates[0]
print(df[['notes', 'shipped_date']])
#                     notes shipped_date
# 0   Shipped on 2024-01-15   2024-01-15
# 1  Delivered on 2024-03-20   2024-03-20
# 2                  Pending          NaN
# 3   Shipped on 2024-07-04   2024-07-04

กลุ่มที่จับแบบมีชื่อ

คุณสามารถตั้งชื่อกลุ่มที่จับได้โดยใช้ไวยากรณ์ (?P<name>...) เมื่อใช้กลุ่มที่มีชื่อกับ str.extract() DataFrame ที่ได้จะใช้ชื่อเหล่านั้นเป็นหัวคอลัมน์โดยอัตโนมัติ ทำให้ผลลัพธ์อธิบายตัวเองได้โดยไม่ต้องเปลี่ยนชื่อคอลัมน์ภายหลัง

import pandas as pd

df = pd.DataFrame({
    'entry': ['Alice (25, Engineer)', 'Bob (30, Manager)', 'Carol (28, Analyst)']
})

# Named capturing groups
extracted = df['entry'].str.extract(
    r'(?P<name>\w+) \((?P<age>\d+), (?P<role>\w+)\)'
)
print(extracted)
#     name age      role
# 0  Alice  25  Engineer
# 1    Bob  30   Manager
# 2  Carol  28   Analyst

ใช้ .str.extractall() เพื่อจับคู่หลายรายการ

.str.extractall(pattern) จะค้นหาการตรงกันทั้งหมดของรูปแบบในแต่ละสตริง (ไม่ใช่แค่ครั้งแรก) โดยส่งคืน DataFrame ที่มี MultiIndex ระดับนอกสุดคือดัชนีแถวเดิม ส่วนระดับใน (match) จะนับจำนวนการตรงกันในแต่ละแถว วิธีนี้มีประโยชน์สำหรับการแยกตัวเลข URL หรือคำสำคัญทั้งหมดจากฟิลด์ข้อความอิสระ

import pandas as pd

df = pd.DataFrame({
    'text': ['Call 555-1234 or 555-5678', 'Contact 800-9000', 'No numbers']
})

# Extract all phone patterns
all_phones = df['text'].str.extractall(r'(\d{3}-\d{4})')
print(all_phones)
#              0
#   match
# 0 0      555-1234
#   1      555-5678
# 1 0      800-9000

ใช้ .str.findall() เพื่อสร้างรายการผลการจับคู่

.str.findall(pattern) จะส่งคืน Series ของรายการ โดยแต่ละรายการประกอบด้วยผลการจับคู่ทั้งหมดที่พบในสตริงของแถวนั้น ต่างจาก extractall() ตรงที่จะไม่สร้าง MultiIndex แต่ละแถวจะได้รับรายการผลการจับคู่ วิธีนี้สะดวกเมื่อคุณต้องการเก็บผลลัพธ์ในโครงสร้างแบบแบนหรือนับจำนวนการจับคู่ต่อแถว

import pandas as pd

df = pd.DataFrame({
    'text': ['Buy 3 items for $10 each', 'Save $5 on 2 products', 'No deal']
})

# Find all dollar amounts
df['prices'] = df['text'].str.findall(r'\$\d+')
df['price_count'] = df['prices'].str.len()

print(df[['text', 'prices', 'price_count']])
#                         text  prices  price_count
# 0  Buy 3 items for $10 each   [$10]            1
# 1  Save $5 on 2 products      [$5]            1
# 2                   No deal      []            0

การจับคู่โดยไม่คำนึงถึงตัวพิมพ์ด้วย re.IGNORECASE

โดยค่าเริ่มต้น regex ใน Pandas จะคำนึงถึงตัวพิมพ์ ให้ส่ง flags=re.IGNORECASE (หรือ re.I) เพื่อให้รูปแบบไม่คำนึงถึงตัวพิมพ์ วิธีนี้ช่วยไม่ให้ต้องเขียนรูปแบบการสลับทางเลือกอย่าง [Pp][Yy][Tt][Hh][Oo][Nn] เมื่อต้องการจับคู่ 'python', 'Python' หรือ 'PYTHON' โดยถือว่าเท่ากัน

import pandas as pd
import re

df = pd.DataFrame({
    'skill': ['Python', 'JAVA', 'javascript', 'PyThOn developer', 'SQL']
})

# Case-insensitive search for python
mask = df['skill'].str.contains('python', flags=re.IGNORECASE, regex=True)
print(df[mask])
#               skill
# 0            Python
# 3  PyThOn developer

การตรวจสอบรูปแบบด้วยการจับคู่ทั้งสตริง

.str.fullmatch(pattern) (เพิ่มใน Pandas 1.1) จะส่งคืนค่า True เฉพาะเมื่อทั้งสตริงตรงกับรูปแบบ ต่างจาก contains() ซึ่งจับคู่สตริงย่อย fullmatch มีผลเทียบเท่ากับการใช้จุดยึด ^...$ นี่เป็นวิธีที่ปลอดภัยที่สุดในการตรวจสอบว่าข้อมูลเป็นไปตามรูปแบบ เช่น ที่อยู่อีเมล หมายเลขโทรศัพท์ รหัสไปรษณีย์ หรือฟิลด์ใด ๆ ที่มีโครงสร้างข้อมูลเข้มงวด

import pandas as pd

df = pd.DataFrame({
    'email': ['alice@example.com', 'bob_at_work', 'carol@test', 'dave@org.co']
})

# Simple email validation: word@word.word
valid_email = df['email'].str.fullmatch(r'[\w.+-]+@[\w-]+\.[\w.]+')
print(df[valid_email])
#                email
# 0  alice@example.com
# 3        dave@org.co

การแทนที่ด้วยการอ้างอิงย้อนกลับของ Regex

เมื่อใช้ str.replace(pattern, repl, regex=True) สตริงที่ใช้แทนสามารถมีการอ้างอิงย้อนกลับ เช่น r'\1' เพื่ออ้างถึงเนื้อหาที่จับไว้ในกลุ่มแรก () วิธีนี้ช่วยให้จัดรูปแบบใหม่ได้อย่างทรงพลัง เช่น เปลี่ยน MM/DD/YYYY เป็น YYYY-MM-DD หรือครอบคำที่จับคู่ได้ด้วยแท็ก HTML

import pandas as pd

df = pd.DataFrame({'phone': ['(555) 123-4567', '(800) 555-0199', '(212) 867-5309']})

# Reformat to 555-123-4567
df['phone_clean'] = df['phone'].str.replace(
    r'\((\d{3})\) (\d{3})-(\d{4})',
    r'\1-\2-\3',
    regex=True
)
print(df)
#             phone phone_clean
# 0  (555) 123-4567  555-123-4567
# 1  (800) 555-0199  800-555-0199
# 2  (212) 867-5309  212-867-5309

การสร้างตัวแยกข้อมูลโดยใช้ Regex

ต่อไปนี้คือตัวอย่างการใช้งานจริงตั้งแต่ต้นจนจบ โดยแยก SKU และราคาผลิตภัณฑ์จากคอลัมน์บันทึกที่ไม่เป็นระเบียบโดยใช้กลุ่มที่มีชื่อ การแยกข้อมูลลักษณะนี้พบได้บ่อยเมื่อนำเข้าข้อมูลจากระบบรุ่นเก่า ซึ่งหลายฟิลด์ถูกนำมาต่อรวมกันเป็นฟิลด์ข้อความเดียว

import pandas as pd

df = pd.DataFrame({
    'note': [
        'SKU:A001 price:$49.99 in stock',
        'SKU:B202 price:$12.50 low stock',
        'No SKU available'
    ]
})

extracted = df['note'].str.extract(
    r'SKU:(?P<sku>\w+).*price:\$(?P<price>[\d.]+)'
)
print(extracted)
#     sku  price
# 0  A001  49.99
# 1  B202  12.50
# 2   NaN    NaN

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับการจับคู่รูปแบบด้วย regex ใน Pandas

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า str.contains(regex) กรองแถวตามรูปแบบ str.extract() จับคู่ครั้งแรกลงในคอลัมน์ DataFrame (ใช้กลุ่มที่มีชื่อเพื่อให้ผลลัพธ์อธิบายตัวเองได้) str.extractall() ค้นหาการจับคู่ทั้งหมดในแต่ละแถวด้วย MultiIndex และ str.fullmatch() ตรวจสอบว่าทั้งสตริงเป็นไปตามรูปแบบ ต่อไปเราจะรวมและทำความสะอาดคอลัมน์ข้อความหลายคอลัมน์

คำถามที่พบบ่อย

บทเรียน “การจับคู่รูปแบบด้วย Regex” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจับคู่รูปแบบด้วย Regex” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจับคู่รูปแบบด้วย Regex”

แยกส่วนย่อยของสตริงและตรวจสอบรูปแบบด้วย .str.extract(), .str.contains() และ .str.match() โดยใช้นิพจน์ทั่วไป คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การจับคู่รูปแบบด้วย Regex” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม

ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แอตทริบิวต์ .str
  2. การแยกและแทนที่สตริง
  3. การจับคู่รูปแบบด้วย Regex
  4. การรวมและทำความสะอาดคอลัมน์ข้อความ
← กลับไปที่ Pandas & NumPy Academy