ก่อนอื่นฉันต้องการเห็นด้วยกับคนอื่น ๆ ว่า regex หรือstr.translate(...)
โซลูชันพื้นฐานนั้นมีประสิทธิภาพมากที่สุด สำหรับกรณีการใช้งานของฉันประสิทธิภาพของฟังก์ชั่นนี้ไม่สำคัญดังนั้นฉันจึงต้องการเพิ่มแนวคิดที่ฉันพิจารณาด้วยเกณฑ์นั้น
เป้าหมายหลักของฉันคือการพูดคุยแนวคิดจากคำตอบอื่น ๆ ในโซลูชันที่สามารถใช้กับสตริงที่มีมากกว่าคำ regex (เช่นบัญชีดำส่วนย่อยที่ชัดเจนของอักขระเครื่องหมายวรรคตอนและตัวอักษรคำที่อนุญาตพิเศษ)
โปรดทราบว่าในวิธีการใดวิธีหนึ่งอาจพิจารณาใช้string.punctuation
แทนรายการที่กำหนดด้วยตนเอง
ตัวเลือก 1 - re.sub
ฉันรู้สึกประหลาดใจที่จะเห็นไม่มีคำตอบเพื่อให้ห่างไกลใช้re.sub ( ... ) ฉันพบว่าวิธีนี้เป็นวิธีที่ง่ายและเป็นธรรมชาติสำหรับปัญหานี้
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
ในโซลูชันนี้ฉันซ้อนการโทรre.sub(...)
ภายในre.split(...)
- แต่ถ้าประสิทธิภาพมีความสำคัญการรวบรวม regex ภายนอกอาจเป็นประโยชน์ - สำหรับกรณีการใช้งานของฉันความแตกต่างไม่สำคัญดังนั้นฉันชอบความเรียบง่ายและอ่านง่าย
ตัวเลือก 2 - str.replace
นี่เป็นอีกสองสามบรรทัด แต่มีประโยชน์ในการขยายได้โดยไม่ต้องตรวจสอบว่าคุณต้องหลบหนีอักขระบางตัวใน regex
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
มันจะเป็นการดีที่สามารถแมป str.replace กับสตริงแทน แต่ฉันไม่คิดว่ามันจะสามารถทำได้ด้วยสายที่ไม่เปลี่ยนรูปและในขณะที่การแมปกับรายชื่อตัวละครจะใช้งานได้ ฟังดูมากเกินไป (แก้ไข: ดูตัวเลือกถัดไปสำหรับตัวอย่างการทำงาน)
ตัวเลือก 3 - functools.reduce
(ใน Python 2 reduce
มีอยู่ในเนมสเปซส่วนกลางโดยไม่ต้องนำเข้าจากฟังก์ชั่นเครื่องมือ)
import functools
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
my_str = functools.reduce(lambda s, sep: s.replace(sep, ' '), replacements, my_str)
words = my_str.split()