มีรายชื่อหรือห้องสมุดที่มีเครื่องหมายวรรคตอนทั้งหมดที่เราอาจพบเจอหรือไม่?
ปกติฉันจะใช้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
เอกสารประกอบของตัวเองเพื่อหาวิธีใช้ทั้งสองอย่าง