2016-02-25 32 views
5

Python 2.6 kullanıyorum ve bir dizede yinelenen karakterleri bulmaya çalışıyorum, bir grup n 'in, örneğin; nnnnnnnABCnnnnnnnnnDEF. Dizenin herhangi bir yerinde n 'sayısı değişken olabilir.Regex, yalnızca dizenin ortasındaki kalıbı bul

Böyle bir regex inşa edin: Sadece gayet dize, başında harf duyarsız n 's tekrarlarını bulabilirsiniz

re.findall(r'^(((?i)n)\2{2,})', s),

. Böyle yaparsam:

re.findall(r'(((?i)n)\2{2,}$)', s),

Ben sadece dizinin sonunda olanları algılayabilir. Peki ya sadece ortada? İlk başta

, ben iade listesinin uzunluğunu ve ya ifadenin başındaki ve sonunda n 's varlığını kontrol ve mantıksal testleri yapmak re.findall(r'(((?i)n)\2{2,})', s) ve önceki iki regex (-ices?) kullanarak düşünce ama çok çabuk çirkin bir şey oldu.

Sonra ben regex sonunda başlayan sadece iyi ama (?!$) veya (?!\z) exlude görünüyor sadece ABCnnnn son n dışlayan, hangi re.findall(r'(?!^)(((?i)n)\2{2,})', s) çalıştı. Sonunda, bazen çalışmak gibi görünen re.findall(r'(?!^)(((?i)n)\2{2,})\w+', s)'u denedim, ancak diğerlerinde garip sonuçlar elde ediyorum. Bir gözüme ya da bakmaya ihtiyacım var gibi geliyor, ama kafamı etraflarına dolamıyorum. n karakterleri eşleştirmeyi reddetmek için karmaşık bir normal ifade kullanmak yerine,

+0

deneyin [ '(<^?!) ((N) \ 2 {2})' (

+0

((? I) n) \ 1 {2} 'nesi yanlış' https://regex101.com/r/oT6vZ1/1? (?

+0

ya da '\ B (n) (? N) \ 1 {2} \ B ' –

cevap

3

.

>>> s = "nnnABCnnnnDEFnnnnnGHInnnnnn" 
>>> import re 
>>> 
>>> re.findall(r'n{2,}', s.strip('n'), re.I) 
['nnnn', 'nnnnn'] 

Not: Daha pythonic yaklaşımı olarak size dize sonra re.findall() kullanılarak n s ve basit bir regex tüm dizisini bulmak strip() olabilir re.I Ignore durum regex yapar bayrağı olduğunu motor, büyük harf ve küçük harf karakterleri ile eşleşir.

+0

'n' bir dizi karakterdir. Onları tahmin etmelisin. –

+0

@ WiktorStribiżew Bu önemli değil, str.strip() 'tüm bağımsız ve sonlanan argümanların sonlarını kaldıracaktır. – Kasramvd

+0

@ WiktorStribiżew: Görünüşe göre 'n' bir karakter, son yorumları görün. –

1

NOT: Bu çözüm n bazı karakterlerin bir dizi olabilir varsayar. n sadece 1 karakter olduğunda daha verimli alternatifler için, burada diğer cevaplara bakın.

Sen regex n s ardışık tekrarlanan maç olacak regex demo

başında ((?<!^)) olmadıklarından emin (görmezden vaka re.I bayrağıyla elde edilebilir) Bkz

(?<!^)(?<!n)((n)\2{2,})(?!$)(?!n) 

kullanabilir veya ((?!n)) ya da daha sonra ((?<!n)) başka bir n dizesinin sonlandırılması ((?!$)).(?<!^)(?<!n)

2 geriye ilerleme dizisidir: (?<!^) dize başlamasıyla öncesinde eğer sonraki desen tüketmek anlamına gelir. (?<!n) negatif Geriye dönük n ile öncesinde bir sonraki desen tüketmeyin gelir. Negatif lookaheads (?!$) ve (?!n) benzer anlamlara sahiptir: Mevcut pozisyon sonrasında dize sonu oluşur ve n dizede mevcut konumda (bu doğru tüm ardışık n s eşleşen sonra, sonra oluşursa (?!n) bir maç başarısız olur ise (?!$) bir maç başarısız .. etrafa bakma koşulları tüm karşılanması gereken, sadece en iç eşleşmeleri almak yüzden

IDEONE demo bakınız: yana

import re 
p = re.compile(r'(?<!^)(?<!n)((n)\2{2,})(?!$)(?!n)', re.IGNORECASE) 
s = "nnnnnnnABCnnnnnNnnnnDEFnNn" 
print([x.group() for x in p.finditer(s)]) 
2

"n", sadece can bir karakterdir (ve bir alt modelin) kullanımı:

re.findall(r'(?<=[^n])nn+(?=[^n])(?i)', s) 

veya daha iyi:

re.findall(r'n(?<=[^n]n)n+(?=[^n])(?i)', s) 
İlgili konular