มีรายชื่อหรือห้องสมุดที่มีเครื่องหมายวรรคตอนทั้งหมดที่เราอาจพบเจอหรือไม่?
ปกติฉันจะใช้string.punctuationแต่เครื่องหมายวรรคตอนบางตัวไม่รวมอยู่ในตัวอย่าง:
>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False
มีรายชื่อหรือห้องสมุดที่มีเครื่องหมายวรรคตอนทั้งหมดที่เราอาจพบเจอหรือไม่?
ปกติฉันจะใช้string.punctuationแต่เครื่องหมายวรรคตอนบางตัวไม่รวมอยู่ในตัวอย่าง:
>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False
คำตอบ:
คุณอาจทำได้ดีกว่าด้วยการตรวจสอบนี้:
>>> import unicodedata
>>> unicodedata.category("'").startswith("P")
True
>>> unicodedata.category("’").startswith("P")
True
หมวดหมู่ Unicode P *ใช้สำหรับเครื่องหมายวรรคตอนโดยเฉพาะ:
คอนเนคเตอร์ (Pc), เส้นประ (Pd), คำพูดเริ่มต้น (Pi), คำพูดสุดท้าย (Pf), เปิด (Ps), ปิด (Pe), ปิด (Pe), อื่น ๆ (Po)
ในการเตรียมคอลเลกชันที่ละเอียดถี่ถ้วนซึ่งคุณสามารถใช้สำหรับการตรวจสอบการเป็นสมาชิกที่รวดเร็วในภายหลังให้ใช้ความเข้าใจชุด:
>>> import sys
>>> from unicodedata import category
>>> codepoints = range(sys.maxunicode + 1)
>>> punctuation = {c for i in codepoints if category(c := chr(i)).startswith("P")}
>>> "'" in punctuation
True
>>> "’" in punctuation
True
การแสดงออกที่ได้รับมอบหมายที่นี่ต้องใช้ Python 3.8 ขึ้นไปเทียบเท่ากับ Python รุ่นเก่า:
chrs = (chr(i) for i in range(sys.maxunicode + 1))
punctuation = set(c for c in chrs if category(c).startswith("P"))
ระวังว่าบางส่วนของตัวละครอื่น ๆ ในstring.punctuationเป็นจริงใน Unicode หมวดหมู่สัญลักษณ์ มันง่ายที่จะเพิ่มสิ่งเหล่านี้เข้าด้วยหากคุณต้องการ
$), Sk (ตัวดัดแปลง, ชอบ^), Sm (คณิตศาสตร์, ชอบ+หรือ<) และบางที (อื่น ๆ เช่น©)
คำตอบที่โพสต์โดย wimนั้นถูกต้องหากคุณต้องการตรวจสอบว่าตัวละครนั้นเป็นตัวอักษรวรรคตอนหรือไม่
หากคุณต้องการรายการอักขระเครื่องหมายวรรคตอนทั้งหมดตามที่ชื่อคำถามของคุณแนะนำคุณสามารถใช้สิ่งต่อไปนี้:
import sys
from unicodedata import category
punctuation_chars = [chr(i) for i in range(sys.maxunicode)
if category(chr(i)).startswith("P")]
คำตอบโดย wimนั้นยอดเยี่ยมถ้าคุณสามารถเปลี่ยนรหัสของคุณเพื่อใช้ฟังก์ชัน
แต่ถ้าคุณต้องใช้inโอเปอเรเตอร์ (ตัวอย่างเช่นคุณโทรเข้ารหัสห้องสมุด) คุณสามารถใช้การพิมพ์เป็ด:
import unicodedata
class DuckType:
def __contains__(self,s):
return unicodedata.category(s).startswith("P")
punct=DuckType()
#print("'" in punct,'"' in punct,"a" in punct)
ดูเหมือนว่าจะเป็นงานที่ดีสำหรับนิพจน์ทั่วไป (regexp)
import re
text = re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE)
ที่นี่ regexp จับคู่ทุกอย่างยกเว้นช่องว่างหรืออักขระคำ การตั้งค่าสถานะre.UNICODEใช้เพื่อจับคู่กับชุดอักขระ Unicode ทั้งหมด
>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
\xc3หลบหนีเป็นสิ่งที่นำเสนอที่ไม่เกี่ยวข้องกับการลอกเครื่องหมายวรรคตอน)
\xc3ไม่ถูกต้อง Unicode เข้ารหัสของæ; ถ้าคุณพิมพ์คุณสามารถยืนยันได้ว่ามันเป็นstr(text) \xc3\xa6จริงๆแล้ว\xc3ดูเหมือนจะไม่ใช่ codepoint ที่สมบูรณ์
strเป็นสตริงไบต์ คุณควรเปลี่ยนไปใช้ Python 3 อย่างแน่นอนเพราะ Unicode เป็นฝันร้ายใน Py2 สำหรับฉันstr('æ')แสดงเป็น'æ'และascii('æ')แสดงเป็น'\xe6'codepoint ที่ถูกต้อง b'\xc3\xa6'เป็นการเข้ารหัสแบบ UTF-8 'æ'แต่นี่ไม่ใช่สิ่งที่คุณต้องการใช้งาน
ตามที่คำตอบอื่น ๆ ได้ชี้ให้เห็นวิธีการทำเช่นนี้คือผ่านคุณสมบัติ / หมวดหมู่ Unicode คำตอบที่ยอมรับจะเข้าถึงข้อมูลนี้ผ่านทางห้องสมุดมาตรฐานunicodedataโมดูลแต่ขึ้นอยู่กับบริบทที่คุณต้องการสิ่งนี้อาจเร็วกว่าหรือสะดวกกว่าในการเข้าถึงข้อมูลคุณสมบัติเดียวกันนี้โดยใช้นิพจน์ทั่วไป
อย่างไรก็ตามreโมดูลไลบรารีมาตรฐานไม่ได้ให้การสนับสนุน Unicode แบบขยาย สำหรับสิ่งที่คุณต้องการregexโมดูลที่มีอยู่ใน PyPI ( pip install regex):
>>> import regex as re
>>> re.match("\p{Punctuation}", "'")
<regex.Match object; span=(0, 1), match="'">
>>> re.match("\p{Punctuation}", "’")
<regex.Match object; span=(0, 1), match='’'>
ภาพรวมที่ดีของทุกชนิดที่แตกต่างกันของคุณสมบัติ Unicode คุณสามารถค้นหาได้โดยใช้การแสดงออกปกติมีให้ที่นี่ นอกเหนือจากคุณสมบัติการแสดงผลปกติเพิ่มเติมเหล่านี้ซึ่งได้รับการบันทึกไว้ในหน้าแรกของ PyPI นั้นregexจงใจให้ API เดียวกับreดังนั้นคุณคาดว่าจะใช้reเอกสารประกอบของตัวเองเพื่อหาวิธีใช้ทั้งสองอย่าง