Python Regex - Cara Mendapatkan Posisi dan Nilai Pertandingan

112

Bagaimana saya bisa mendapatkan posisi awal dan akhir dari semua pertandingan menggunakan remodul? Misalnya diberikan pola r'[a-z]'dan string 'a1b2c3d4'saya ingin mendapatkan posisi di mana ia menemukan setiap huruf. Idealnya, saya juga ingin mendapatkan teks pertandingan kembali.

Greg
sumber
Lihat apakah ini membantu Match Objects
EBGreen

Jawaban:

140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())
Peter Hoffmann
sumber
3
Ini tidak memberikan indeks grup lain dalam pertandingan regex = r '([az]) (0-9)' m.start akan untuk grup (), bukan grup (1)
StevenWernerCS
@StevenWernerCS start()dapat menerima nomor grup, jadi jika Anda ingin indeks grup ke-n, gunakanstart(n)
Hi-Angel
@ hi-angel ya, lihat jawaban saya di bawah ini dari tahun lalu yang melakukan hal itu
StevenWernerCS
51

Diambil dari

Ekspresi Reguler HOWTO

span () mengembalikan indeks awal dan akhir dalam satu tupel. Karena metode match hanya memeriksa apakah RE cocok di awal string, start () akan selalu nol. Namun, metode pencarian contoh RegexObject memindai melalui string, sehingga kecocokan mungkin tidak dimulai dari nol dalam kasus itu.

>>> 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)

Gabungkan itu dengan:

Di Python 2.2, metode finditer () juga tersedia, mengembalikan urutan instance MatchObject sebagai iterator.

>>> 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)

Anda harus dapat melakukan sesuatu dengan urutan

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()
hilang
sumber
Anda dapat menggunakannya seperti re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван
'Indeks akhir' yang dikembalikan oleh span()adalah seperti 'stop' dalam notasi potongan Python yang naik ke atas tetapi tidak menyertakan indeks itu; lihat disini .
Wayne
20

Untuk Python 3.x

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

Anda akan mendapatkan \ntupel terpisah (masing-masing terdiri dari indeks pertama dan terakhir dari pertandingan) dan pertandingan itu sendiri, untuk setiap pukulan dalam string.

Rams Here
sumber
2

perhatikan bahwa span & group diindeks untuk multi capture group dalam regex

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))
StevenWernerCS
sumber
1
Terima kasih, ini terbukti sangat berguna dan tampaknya cukup terkubur. Selain itu, jika ada yang membutuhkan ini: saat menggunakan grup tangkap bernama, seseorang dapat menemukan indeks grup menggunakan <match> .re.groupindex, dan dari sana temukan rentang yang sesuai menggunakan pendekatan yang Anda uraikan
madimov
darimana 4asalnya
Radio Controlled
@RadioControlled number_of_known_groups_in_the_regex + 1, karena jangkauannya [awal, akhir) eksklusif akhir
StevenWernerCS
@StevenWernerCS sehingga tidak menggeneralisasi kasus-kasus di mana jumlah grup tidak diketahui ...
Radio Controlled