การจับคู่รูปแบบด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แอตทริบิวต์ .str
- การแยกและแทนที่สตริง
- การจับคู่รูปแบบด้วย Regex
- การรวมและทำความสะอาดคอลัมน์ข้อความ