2012-12-01 22 views
6

Ben Pyparsing (ve oldukça yeni Python için) yeniyim. Sorunumu aşağı doğru neyin yanlış olduğunu gösterecek en basit forma indirmeye çalıştım (muhtemelen muhtemelen Pyparsing'e gerek duymayacağım noktaya kadar!)Pyparsing acemi setParseAction değiştirerek belirteçleri

Mektup ve rakamlardan oluşan bir dizim olduğunu varsayalım "b7 z4 a2 de c3" gibi. Her zaman bir mektup var, ama numara isteğe bağlı. Bunu kendi bireysel unsurlarına ayrıştırmak ve daha sonra bunları işlemek istiyorum, ancak hiçbir rakamı olmayan, çıplak bir harfin olduğu yerde, onu değiştirmek için kullanışlı olacaktır, böylece "varsayılan" 1 numaralı numara daha sonra vardı. Sonra her elemanı tutarlı bir şekilde işleyebilirim.

from pyparsing import * 
teststring = "a2 b5 c9 d e z" 
expected_letter = Word("ABCDEFGabcdefgzZxy", exact=1) 
expected_number = Word(nums) 
letter_and_number = expected_letter + expected_number 
bare_letter = expected_letter 
bare_letter.setParseAction(lambda s,l,t: t.append("1")) 
elements = letter_and_number | bare_letter 
line = OneOrMore(elements) 
print line.parseString(teststring) 

Maalesef t.append() Bir "1" listesine eklemek, hangi bekliyorum ne yapmaz şu şekildedir: Ben bir setparseAction ile bu yapabileceğini düşündüm ayrıştırılmış jetonlar. Bunun yerine, bir hata alıyorum: TypeError: 'str' nesnesi callable değil.

Ben muhtemelen sadece burada, gerçekten kalın olmak, ancak uzmanlardan biri bana düz ayarlamak misiniz.

Teşekkür

Steve pyparsing hakkında almak için temel kavramların

cevap

4

biri dizeleri sadece listeleri ile çalışmadığını, ancak ParseResults nesnesine ayrıştırılır parçaları toplanır. ParseResults tanımlı bir sonucu adı olan bir ParserElement ayrıştırılan edilmiştir belirteçleri varsa bir liste ya da bir dict veya nesne olarak erişilebilir pyparsing tanımlanan zengin bir veri türü vardır. ParseResults akılda kolay erişim ile tasarlanmış iken

Ancak, bunun güncellenebilir şekilde sınırlıdır. Püskürtme içinde dahili olarak, eşleşen her ifade küçük bir ParseResults nesnesi oluşturur; Bu büyük bir ifadenin parçasıysa, bu ifade parçaları + = operatörünü kullanarak büyük bir ParseResults içine biriktirir.

t += ParseResults("1") 

Maalesef bu bir lambda olarak çalışmaz: Senin durumunda

, burada "1" içeren ve t eklemeden küçük ParseResults yaratarak geçirilir ParseResults ekleyebileceğiniz -

lambda s,l,t: t.__iadd__(ParseResults("1")) 

Ancak, bu biraz akıllıca hissedebilirsiniz.

Ayrıca opsiyonel sınıfın yararlanmak, sizin ayrıştırıcı biraz düşünmek olabilir. Sondaki hanenizi, öğenin eksik olması durumunda sağlamak için varsayılan bir değer tanımlayabileceğiniz isteğe bağlı bir öğe olarak düşünün. vb

(Normalde searchString iadeler

>>> letter = Word(alphas,exact=1) 
>>> digit = Word(nums,exact=1) 
>>> teststring= "a2 b5 c9 d e z" 
>>> letter_and_digit = Combine(letter + Optional(digit, default="1")) 
>>> print (sum(letter_and_digit.searchString(teststring))) 
['a2', 'b5', 'c9', 'd1', 'e1', 'z1'] 

aksi her maç ['a','2'], ['b','5'] gibi görünecektir, dizeleri içine ayrı harf ve rakamları yeniden katılmak için kullanılır birleştirin: Az önce birlikte istediğini tanımlayabilirsiniz düşünüyorum Tek öğe listelerinin bir listesi gibi görünecek ParseResults nesnelerinin bir listesi. SearchString'in sonuçlarını sum'a geçirerek bunların hepsini yalnızca bir ParseResults dizesine ekler.)

+0

Ah evet, bu şimdi mükemmel bir anlam ifade ediyor! Ayrıştırma sonuçlarını yazdırdığımda, normal bir liste gibi görünüyorlardı, bu yüzden her zamanki gibi ekleyebileceğimi düşündüm. Ayrıca Isteğe bağlı bir genel çözüm sağlayan bir varsayılan ayar sağlar gerçeğini özledim.Ve gerçek programım için geçerli olacak, ki bu da buradaki indirilmiş versiyondan biraz daha karmaşık. yardımınız için çok teşekkürler ... ve kendini Pyparsing için! Steve. –