Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การจับคู่รูปแบบชื่อไฟล์ Unix ใน Python (fnmatch)

รูปแบบวิลด์การ์ด (wildcard patterns) ที่ใช้ในบรรทัดคำสั่ง Unix shell แตกต่างจากไวยากรณ์ regular expression ในไลบรารีมาตรฐานของ Python โมดูล fnmatch ให้การจับคู่รูปแบบวิลด์การ์ดแบบ Unix

ฟังก์ชันต่อไปนี้ถูกกำหนดในโมดูล fnmatch:

fnmatch()

ฟังก์ชันนี้ต้องการ 2 พารามิเตอร์ - ชื่อไฟล์ และรูปแบบสตริงของตัวอักษร ชื่อไฟล์ถูกจับคู่กับรูปแบบที่ให้มา และฟังก์ชันคืนค่า True หรือ False

ตัวอย่างต่อไปนี้แสดงรายการไฟล์ทั้งหมดที่จับคู่กับรูปแบบ "*.py" จากไดเรกทอรีปัจจุบัน:

>>> import glob, fnmatch
>>> for files in (glob.glob('*.*')):
...     if (fnmatch.fnmatch(files, "*.py")):
...         print(files)

fnmatchcase()

ฟังก์ชันนี้คล้ายกับ fnmatch() อย่างไรก็ตาม ฟังก์ชันนี้ดำเนินการจับคู่รูปแบบกับชื่อไฟล์แบบ case sensitive (แยกตัวพิมพ์ใหญ่-เล็ก):

ในตัวอย่างต่อไปนี้ ไฟล์ทั้งหมดที่ชื่อขึ้นต้นด้วย 'l' และนามสกุล '.py' ถูกเก็บรวบรวมในอ็อบเจ็กต์รายการ files ฟังก์ชัน fnmatch() ถูกนำไปใช้เพื่อพิมพ์เฉพาะชื่อที่ขึ้นต้นด้วยตัวอักษร 'lo':

>>> files = glob.glob("l*.*")
>>> files
['LICENSE.txt', 'lines.txt', 'listwidget.ui', 'lo1.ui', 'lo2.ui', 'lo3.ui', 'logo.png', 'logo.svg', 'lw.ui']
>>> for file in files:
...     if fnmatch.fnmatchcase(file, "lo*.*") == True:
...         print(file)
lo1.ui
lo2.ui
lo3.ui
logo.png
logo.svg

filter()

ฟังก์ชันนี้คืนค่าเฉพาะไฟล์ที่ชื่อจับคู่กับพารามิเตอร์รูปแบบที่ให้มา:

คำสั่งต่อไปนี้คืนค่ารายการไฟล์ที่มีนามสกุล '.txt' จากไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน:

>>> fnmatch.filter(files, "*.txt")
['a!.txt', 'data().txt', 'dict.txt', 'json.txt', 'LICENSE.txt', 'lines.txt', 'msg.txt', 'NEWS.txt', 'test.txt', 'zen.txt', 'zen1.txt', 'zenbak.txt']

translate()

ฟังก์ชันนี้มีประโยชน์ในการแปลงรูปแบบแบบ UNIX ให้เป็นรูปแบบ RegEx ที่สอดคล้อง ค่าที่คืนจากฟังก์ชัน translate() ควรแปลงเป็น regular expression โดยใช้ฟังก์ชัน compile() ของโมดูล re นี่จึงถูกใช้เพื่อจับคู่รูปแบบ:

>>> pattern = "*.txt"
>>> import re
>>> reg = fnmatch.translate(pattern)
>>> reg
'(?s:.*\\.txt)\\Z'
>>> rec = re.compile(reg)
>>> for file in glob.glob("*.*"):
...     if re.match(rec, file):
...         print(file)

ในบทความนี้ ฟังก์ชันในโมดูล fnmatch ได้รับการอธิบาย