2015-12-30 15 views
9

Vurgulamak için, "regex kullanarak ayrıştırmak" istemiyorum - "sembolik bir ağacın içine bir regex ayrıştırmak istiyorum." (Searching sadece eski getirdi ...)Regex'i AST'ye ayrıştırmak için Python kitaplığı?

Kullanım durumum: bir veritabanı üzerinden normal ifade aramayı hızlandırmak için (foo|bar)baz+(bat)* gibi bir regex ayrıştırmak ve bir ekranda görünmesi gereken tüm alt dizeleri çıkarmak istiyorum maç. (Bu durumda, sadece baz çünkü foo/bar dönüşümlüdür ve yarasa 0 kez görünebilir.)

Bunu yapmak için, düzenli ifade işleçleri/anlambilimine biraz ihtiyacım var.

In [7]: re.compile('(foo|bar)baz+(bat)', re.DEBUG) 
subpattern 1 
    branch 
    literal 102 
    literal 111 
    literal 111 
    or 
    literal 98 
    literal 97 
    literal 114 
literal 98 
literal 97 
max_repeat 1 4294967295 
    literal 122 
subpattern 2 
    literal 98 
    literal 97 
    literal 116 

Ancak, sadece dışarı baskı, ve c-uygulama sonrasında bildiğim kadarıyla söyleyebilirim yapısını korumak değildir: re.DEBUG yakın geliyor. Sahip ayrıştırıcımı yazmadan nasıl ayrılabileceğime dair herhangi bir fikir var mı? Bunun anlamı

regex = { alternatives }; 
alternatives = primitive { '|' alternatives } ; 
primitive = '(' regex ')' | '[' character_set ']' | ... 

Bir düzenli ifade (Perl, ama sonra onun "regexes bir istisnadır kullanarak regex ayrıştıramadı:

+2

nasıl regeg üzerinde bir normal ifade kullanma hakkında Desen? – Netwave

+4

@DanielSanchez Düzenli ifadeleri normal ifadelerle ayrıştıramazsınız. – BlackJack

+0

@BlackJack, regex dizesini yeniden düzenleyebilir, yani regex için "1 | 2" varsa, bu dizeyi yeniden düzenleyebilirim. – Netwave

cevap

2

Yalnızca bir bağlam serbest dilbilgisi kullanarak (klasik) regex belirtebilirsiniz "klasik" nin ötesinde bir şekilde genişletilmiştir.

Yani, bir normal ifadeyi ayrıştırmak için, kendi çözümleyicinizi oluşturmanız ve bir çeşit ağacın (re.Debug oldukça yakın geliyor) veya umduğunuz büyü kitaplığını oluşturmanız gerekir.

Bunun çok kolay olduğundan şüpheleniyorum. Bu kendini yapmak için çok zor değil; Böyle ayrıştırıcılar oluşturmak için basit bir şema için bakınız Is there an alternative for flex/bison that is usable on 8-bit embedded systems?.

semantik regex ait anlamak için (dibini Bir analizörü Çözümleme ağacının üzerinde yürür bina ile kurtulmak mümkün olabilir, (örneğin, "gerekli alt dizeleri" anlamaya) ve her alt ağaç için yukarı), ortak dizgiyi hesaplar. Klasik NDFA inşasını uygulamak ve daha sonra üzerine yürümek veya NDFA'yı DFA inşaatına uygulamak ve DFA'nın üzerinde yürümek zorunda kalabilirsiniz. Gerçek ifadeler, yerleşik karakter kümeleri, yakalama grupları vb. Gibi dağınık bir çok karmaşıklık içermeye eğilimlidir.

"Ortak dize", yalnızca bu şekilde dar bir şekilde tanımlanabilmenize rağmen, yalnızca bitişik bir karakter dizisi olmayabilir. Karakterlerin sabit veya değişken uzunluk boşlukları ayırarak birkaç sabit alt dizeleri içerebilir, örneğin, sizin gerekli alt dize hep kendisi formun "basit regex" olarak ifade edilebilir olabilir:

(<character>+ ?+) <character>+ 
+0

Evet, NDFA ya da ayrıştırma ağacının üzerinden geçmeme izin veren bir regex kitaplığı olduğunu umuyordum; ANTLR ve benzerlerini birkaç kez kullandım ve hiç kaçırmayın ...re: "basit regex", günün sonunda gerekli alt dizelerin bulunmadığı (ab +) * 'gibi örneklerle komplikasyonlara çarparsınız. Her neyse, perspektif için teşekkürler, bu yararlıdır (her ne kadar herkesin kendimi ayrıştırmaktan kurtaracağım fikrinin olması durumunda soruyu açık tutacak olmasına rağmen) – munchybunch

İlgili konular