Python Regex - Eşleşmelerin Konumlarını ve Değerlerini Alma


112

reModülü kullanarak tüm maçların başlangıç ​​ve bitiş konumlarını nasıl alabilirim ? Örneğin, desen r'[a-z]'ve dize verildiğinde, 'a1b2c3d4'her harfi bulduğu konumları almak istiyorum. İdeal olarak, maçın metnini de geri almak isterim.


Yanıtlar:


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

3
Bu, bir normal ifadedeki diğer grupların dizinini sağlamaz = r '([az]) (0-9)' m.start, grup () için olacak, grup (1) için olmayacak
StevenWernerCS

@StevenWernerCS start()bir grup numarasını kabul edebilir, bu nedenle n'inci grubun bir dizinini istiyorsanızstart(n)
Hi-Angel

@ merhaba-melek evet, geçen yılki cevabımı aşağıdan görün, tam da bunu yapar
StevenWernerCS

51

Den alınan

Normal İfade NASIL

span (), tek bir dizide hem başlangıç ​​hem de bitiş dizinlerini döndürür. Eşleşme yöntemi yalnızca RE'nin bir dizenin başında eşleşip eşleşmediğini kontrol ettiğinden, start () her zaman sıfır olacaktır. Ancak, RegexObject örneklerinin arama yöntemi dizeyi tarar, bu nedenle bu durumda eşleşme sıfırdan başlamayabilir.

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

Bunu şununla birleştir:

Python 2.2'de, bir dizi MatchObject örneğini yineleyici olarak döndüren finditer () yöntemi de mevcuttur.

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

sırasına göre bir şeyler yapabilmelisin

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

Bunu şu şekilde kullanabilirsiniz re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван

Tarafından döndürülen 'bitiş indeksi' span(), Python'un dilim gösterimindeki 'durdurma' gibidir, çünkü bu indeksi içermez, ancak yükselir; buraya bakın .
Wayne

20

Python 3.x için

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

\nDizedeki her vuruş için ayrılmış tuplelar (sırasıyla maçın ilk ve son indekslerini içerir) ve maçın kendisi alacaksınız .


2

yayılma ve grubun bir normal ifadede çoklu yakalama grupları için dizine alındığını unutmayın

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
Teşekkürler, bu çok yararlı oldu ve oldukça gömülü görünüyor. Ayrıca, herhangi birinin buna ihtiyacı olması durumunda: adlandırılmış yakalama gruplarını kullanırken, <match> .re.groupindex'i kullanarak bir grubun dizinini bulabilir ve buradan, özetlediğiniz yaklaşımı kullanarak karşılık gelen aralığı bulabilirsiniz
madimov

nereden 4geliyor
Radyo Kontrollü

@RadioControlled number_of_known_groups_in_the_regex + 1, aralık [başlangıç, bitiş) dışında olduğu için
StevenWernerCS

@StevenWernerCS, bu nedenle grup sayısının bilinmediği durumlara genellemez ...
Radyo Kontrollü
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.