Python Regex - วิธีรับตำแหน่งและค่าของการจับคู่


112

ฉันจะรับตำแหน่งเริ่มต้นและตำแหน่งสิ้นสุดของการแข่งขันทั้งหมดโดยใช้reโมดูลได้อย่างไร ตัวอย่างเช่นกำหนดรูปแบบr'[a-z]'และสตริง'a1b2c3d4'ฉันต้องการรับตำแหน่งที่พบแต่ละตัวอักษร ตามหลักการแล้วฉันต้องการรับข้อความของการแข่งขันกลับด้วย


ดูว่าสิ่งนี้ช่วยMatch Objects หรือไม่
EBGreen

คำตอบ:


140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())

3
สิ่งนี้ไม่ได้ให้ดัชนีของกลุ่มอื่น ๆ ในการจับคู่ regex = r '([az]) (0-9)' m การเริ่มต้นจะเป็นสำหรับกลุ่ม () ไม่ใช่กลุ่ม (1)
StevenWernerCS

@StevenWernerCS start()อาจยอมรับหมายเลขกลุ่มดังนั้นหากคุณต้องการดัชนีของกลุ่มที่ n ให้ใช้start(n)
Hi-Angel

@ hi-angel ใช่ดูคำตอบของฉันด้านล่างจากปีที่แล้วที่ทำแบบนั้น
StevenWernerCS

51

เอามาจาก

นิพจน์ทั่วไป HOWTO

span () ส่งคืนทั้งดัชนีเริ่มต้นและสิ้นสุดในทูเพิลเดียว เนื่องจากวิธีการจับคู่จะตรวจสอบว่า RE ตรงกันที่จุดเริ่มต้นของสตริงเท่านั้น start () จะเป็นศูนย์เสมอ อย่างไรก็ตามวิธีการค้นหาของอินสแตนซ์ RegexObject จะสแกนผ่านสตริงดังนั้นการจับคู่อาจไม่เริ่มต้นที่ศูนย์ในกรณีนั้น

>>> p = re.compile('[a-z]+')
>>> print p.match('::: message')
None
>>> m = p.search('::: message') ; print m
<re.MatchObject instance at 80c9650>
>>> m.group()
'message'
>>> m.span()
(4, 11)

รวมเข้ากับ:

ใน Python 2.2 เมธอด finditer () จะพร้อมใช้งานโดยส่งคืนลำดับของอินสแตนซ์ MatchObject เป็นตัววนซ้ำ

>>> p = re.compile( ... )
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable-iterator object at 0x401833ac>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)

คุณควรจะทำบางอย่างตามลำดับ

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()

คุณสามารถใช้มันเช่นre.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
КонстантинВан

'end index' ที่ส่งกลับโดย the span()เป็นเหมือน 'stop' ในสัญกรณ์ slice ของ Python ที่มันขึ้นไป แต่ไม่รวมดัชนีนั้น ดูที่นี่ .
Wayne

20

สำหรับ Python 3.x

from re import finditer
for match in finditer("pattern", "string"):
    print(match.span(), match.group())

คุณจะได้รับ\ntuples ที่แยกจากกัน (ประกอบด้วยดัชนีแรกและดัชนีสุดท้ายของการแข่งขันตามลำดับ) และการจับคู่นั้นเองสำหรับแต่ละ Hit ในสตริง


2

โปรดทราบว่าช่วงและกลุ่มได้รับการจัดทำดัชนีสำหรับกลุ่มการบันทึกหลายกลุ่มในนิพจน์ทั่วไป

regex_with_3_groups=r"([a-z])([0-9]+)([A-Z])"
for match in re.finditer(regex_with_3_groups, string):
    for idx in range(0, 4):
        print(match.span(idx), match.group(idx))

1
ขอบคุณสิ่งนี้พิสูจน์แล้วว่ามีประโยชน์มากและดูเหมือนว่าจะถูกฝังอยู่ นอกจากนี้ในกรณีที่ใครก็ตามต้องการสิ่งนี้: เมื่อใช้กลุ่มการจับที่ตั้งชื่อเราสามารถค้นหาดัชนีของกลุ่มโดยใช้ <match> .re.groupindex และจากนั้นให้ค้นหาช่วงที่สอดคล้องกันโดยใช้วิธีการที่คุณระบุไว้
madimov

ที่ใด4มาจากไหน?
วิทยุควบคุม

@RadioControlled number_of_known_groups_in_the_regex + 1 เนื่องจากช่วงคือ [เริ่มต้นสิ้นสุด) ไม่รวมจุดสิ้นสุด
StevenWernerCS

@StevenWernerCS ดังนั้นจึงไม่ได้กล่าวถึงกรณีที่ไม่ทราบจำนวนกลุ่ม ...
Radio Controlled
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.