การจับคู่สตริง Python โดยไม่มีไวยากรณ์ RegEx ที่ซับซ้อน

การจับคู่สตริง Python โดยไม่มีไวยากรณ์ RegEx ที่ซับซ้อน

โหนดต้นทาง: 1935271

การจับคู่สตริง Python โดยไม่มีไวยากรณ์ RegEx ที่ซับซ้อน
ภาพโดยผู้เขียน
 

ฉันมีความสัมพันธ์ทั้งรักทั้งเกลียดกับ Regular Expression (RegEx) โดยเฉพาะใน Python ฉันชอบวิธีที่คุณสามารถแยกหรือจับคู่สตริงโดยไม่ต้องเขียนฟังก์ชันเชิงตรรกะหลายตัว มันดีกว่าฟังก์ชั่นการค้นหาสตริง 

สิ่งที่ฉันไม่ชอบคือการเรียนรู้และเข้าใจรูปแบบ RegEx เป็นเรื่องยากสำหรับฉัน ฉันสามารถจัดการกับการจับคู่สตริงอย่างง่าย เช่น การแยกอักขระที่เป็นตัวอักษรและตัวเลขทั้งหมด และล้างข้อความสำหรับงาน NLP สิ่งต่าง ๆ ยากขึ้นเมื่อต้องแยกที่อยู่ IP อีเมล และ ID จากข้อความขยะ คุณต้องเขียนรูปแบบสตริง RegEx ที่ซับซ้อนเพื่อแยกรายการที่ต้องการ 

ในการทำให้งาน RegEx ที่ซับซ้อนเป็นเรื่องง่าย เราจะเรียนรู้เกี่ยวกับ Python Package อย่างง่ายที่เรียกว่า คำนำหน้านาม. นอกจากนี้ เราจะดูตัวอย่างบางส่วนของการแยกวันที่และอีเมลจากข้อความยาวๆ  

พรีเจ็กซ์ เป็น API ระดับสูงกว่าที่สร้างขึ้นจากโมดูล `re` เป็น RegEx ที่ไม่มีรูปแบบ RegEx ที่ซับซ้อน ซึ่งช่วยให้โปรแกรมเมอร์เข้าใจและจดจำ Regular Expression ได้ง่าย ยิ่งไปกว่านั้น คุณไม่จำเป็นต้องจัดกลุ่มรูปแบบหรือหลีกเลี่ยงอักขระเมตา และเป็นแบบโมดูลาร์ 

คุณสามารถติดตั้งไลบรารีโดยใช้ PIP

pip install pregex

 

เพื่อทดสอบการทำงานที่มีประสิทธิภาพของ PREgEx เราจะใช้โค้ดตัวอย่างที่แก้ไขแล้วจาก เอกสาร

ในตัวอย่างด้านล่าง เรากำลังแยกที่อยู่ HTTP URL หรือที่อยู่ IPv4 ด้วยหมายเลขพอร์ต เราไม่ต้องสร้างตรรกะที่ซับซ้อนให้กับมัน เราสามารถใช้ฟังก์ชันในตัว `HttpUrl` และ `IPv4`

  1. สร้างหมายเลขพอร์ตโดยใช้ AnyDigit() ตัวเลขตัวแรกของพอร์ตไม่ควรเป็นศูนย์ และตัวเลขสามตัวถัดไปสามารถเป็นตัวเลขใดก็ได้ 
  2. ใช้ Either() เพื่อเพิ่มหลายลอจิกเพื่อแยก HTTP URL หรือที่อยู่ IP พร้อมหมายเลขพอร์ต 
from pregex.core.pre import Pregex
from pregex.core.classes import AnyDigit
from pregex.core.operators import Either
from pregex.meta.essentials import HttpUrl, IPv4 port_number = (AnyDigit() - '0') + 3 * AnyDigit() pre = Either( HttpUrl(capture_domain=True, is_extensible=True), IPv4(is_extensible=True) + ':' + port_number
)

 

เราจะใช้สตริงข้อความยาวพร้อมอักขระและคำอธิบาย 

text = """IPV4--192.168.1.1:8000-- address--https://www.abid.works-- website--https://kdnuggets.com--text"""

 

ก่อนที่เราจะแยกสตริงที่ตรงกัน มาดูรูปแบบ RegEx กันก่อน 

regex_pattren = pre.get_pattern()
print(regex_pattren)

 

เอาท์พุต

อย่างที่เราเห็น มันยากที่จะอ่านหรือเข้าใจสิ่งที่เกิดขึ้น นี่คือจุดที่ PREgEx เปล่งประกาย เพื่อมอบ API ที่เป็นมิตรกับมนุษย์สำหรับการทำงานนิพจน์ทั่วไปที่ซับซ้อน 

(?:https?://)?(?:www.)?(?:[a-zdA-Z][a-z-dA-Z]{,61}[a-zdA-Z].)*([a-zdA-Z][a-z-dA-Z]{,61}[a-zdA-Z]).[a-z]{2,6}(?::d{1,4})?(?:/[!-.0-~]+)*/?(?:(?=[!-/[-`{-~:-@])|(?=w))|(?:(?:d|[1-9]d|1d{2}|2(?:[0-4]d|5[0-5])).){3}(?:d|[1-9]d|1d{2}|2(?:[0-4]d|5[0-5])):[1-9]d{3}

 

เช่นเดียวกับ `re.match` เราจะใช้ `.get_matches(text)` เพื่อแยกสตริงที่ต้องการ

results = pre.get_matches(text)
print(results)

 

เอาท์พุต

เราได้แยกทั้งที่อยู่ IP พร้อมหมายเลขพอร์ตและ URL ของเว็บสองรายการ 

['192.168.1.1:8000', 'https://www.abid.works', 'https://kdnuggets.com']

ลองดูตัวอย่างสองสามตัวอย่างที่เราสามารถเข้าใจศักยภาพทั้งหมดของ PREgEx 

ในตัวอย่างนี้ เราจะแยกรูปแบบวันที่บางประเภทออกจากข้อความด้านล่าง

text = """ 04-15-2023 2023-08-15 06-20-2023 06/24/2023 """

 

โดยใช้ Exactly() และ AnyDigit() เราจะสร้างวัน เดือน และปีของวันที่ วันและเดือนมี 4 หลัก ส่วนปีมี XNUMX หลัก คั่นด้วยเครื่องหมาย "-"

หลังจากสร้างรูปแบบแล้ว เราจะเรียกใช้ `get_match` เพื่อแยกสตริงที่ตรงกัน 

from pregex.core.classes import AnyDigit
from pregex.core.quantifiers import Exactly day_or_month = Exactly(AnyDigit(), 2) year = Exactly(AnyDigit(), 4) pre = ( day_or_month + "-" + day_or_month + "-" + year
) results = pre.get_matches(text)
print(results)

 

เอาท์พุต

['04-15-2023', '06-20-2023']

 

มาดูรูปแบบ RegEx โดยใช้ฟังก์ชัน `get_pattern()` 

regex_pattren = pre.get_pattern()
print(regex_pattren)

 

เอาท์พุต

อย่างที่เราเห็น มันมีไวยากรณ์ RegEx ที่เรียบง่าย 

d{2}-d{2}-d{4}

ตัวอย่างที่สองค่อนข้างซับซ้อน โดยเราจะแยกที่อยู่อีเมลที่ถูกต้องออกจากข้อความขยะ 

text = """ user1@abid.works editorial@@kdnuggets.com lover@python.gg. editorial1@kdnuggets.com """

 

  • สร้าง ผู้ใช้งาน รูปแบบที่มี `OneOrMore()` เราจะใช้ `AnyButFrom()` เพื่อลบ "@" และช่องว่างออกจากตรรกะ 
  • คล้ายกับ a ผู้ใช้งาน รูปแบบที่เราสร้าง บริษัท รูปแบบโดยลบอักขระเพิ่มเติม “.” จากตรรกะ
  • สำหรับ โดเมน,  เราจะใช้ `MatchAtLineEnd()` เพื่อเริ่มการค้นหาจากจุดสิ้นสุดด้วยอักขระสองตัวหรือมากกว่า ยกเว้น “@” ช่องว่าง และจุดสิ้นสุด  
  • รวมทั้งสามเพื่อสร้างรูปแบบสุดท้าย: user@company.domain.
from pregex.core.classes import AnyButFrom
from pregex.core.quantifiers import OneOrMore, AtLeast
from pregex.core.assertions import MatchAtLineEnd user = OneOrMore(AnyButFrom("@", ' '))
company = OneOrMore(AnyButFrom("@", ' ', '.'))
domain = MatchAtLineEnd(AtLeast(AnyButFrom("@", ' ', '.'), 2)) pre = ( user + "@" + company + '.' + domain
) results = pre.get_matches(text)
print(results)

 

เอาท์พุต

อย่างที่เราเห็น PRegEx ได้ระบุที่อยู่อีเมลที่ถูกต้องสองรายการ 

['user1@abid.works', 'editorial1@kdnuggets.com']

 

หมายเหตุ ตัวอย่างโค้ดทั้งสองเป็นเวอร์ชันแก้ไขของงานโดย PyCoach

หากคุณเป็นนักวิทยาศาสตร์ข้อมูล นักวิเคราะห์ หรือผู้ที่ชื่นชอบ NLP คุณควรใช้ PREgEx เพื่อล้างข้อความและสร้างตรรกะง่ายๆ มันจะลดการพึ่งพาเฟรมเวิร์ก NLP เนื่องจากการจับคู่ส่วนใหญ่สามารถทำได้โดยใช้ API แบบง่าย 

ในบทช่วยสอนขนาดเล็กนี้ เราได้เรียนรู้เกี่ยวกับแพ็คเกจ Python PRegEx และกรณีการใช้งานพร้อมตัวอย่าง คุณสามารถเรียนรู้เพิ่มเติมได้โดยอ่านอย่างเป็นทางการ เอกสาร หรือแก้ก คำ ปัญหาการใช้ Regular Expression ที่ตั้งโปรแกรมได้

 
 
อาบิด อาลี อาวัน (@1อบีดาลิวัน) เป็นนักวิทยาศาสตร์ข้อมูลที่ได้รับการรับรองมืออาชีพที่รักการสร้างแบบจำลองการเรียนรู้ของเครื่อง ปัจจุบันเขามุ่งเน้นไปที่การสร้างเนื้อหาและการเขียนบล็อกทางเทคนิคเกี่ยวกับการเรียนรู้ของเครื่องและเทคโนโลยีวิทยาศาสตร์ข้อมูล อาบิดสำเร็จการศึกษาระดับปริญญาโทด้านการจัดการเทคโนโลยีและปริญญาตรีสาขาวิศวกรรมโทรคมนาคม วิสัยทัศน์ของเขาคือการสร้างผลิตภัณฑ์ AI โดยใช้โครงข่ายประสาทเทียมแบบกราฟสำหรับนักเรียนที่ป่วยเป็นโรคทางจิต
 

ประทับเวลา:

เพิ่มเติมจาก KD นักเก็ต

KDnuggets™ News 21:n44, 17 พ.ย.: อย่าเสียเวลาไปกับการสร้างเครือข่ายวิทยาศาสตร์ข้อมูลของคุณ 19 แนวคิดโครงงานวิทยาศาสตร์ข้อมูลสำหรับผู้เริ่มต้น

โหนดต้นทาง: 1570438
ประทับเวลา: พฤศจิกายน 17, 2021