2016-03-11 12 views
5

Örneğin, "2 x 4" gibi dönüştürmek istediğim çok sayıda ürün boyutuna sahip bir metin var. Ben ne yapmak istediğinizi tarif etmeninDüzenli olarak yinelenen değiştiriyor gibi regex'in tüm yinelemelerini nasıl değiştirilir?

pattern = r"([0-9])\s*[xX\*]\s*([0-9])" 

re.sub(pattern, r"\1 xby \2", "2x4") 
'2 xby 4' # good 

re.sub(pattern, r"\1 xby \2", "2x4x12") 
'2 xby 4x12' # not good. need this to be '2 xby 4 xby 12' 

bir yolu artık değiştirmeler yapılabilir kadar değiştirilmesini tekrarlamak olduğunu. Örneğin, ben sadece yukarıdaki değiştirilmesi için iki kez

x = re.sub(pattern, r"\1 xby \2", "2x4x12") 
x = re.sub(pattern, r"\1 xby \2", x) 
'2 xby 4 xby 12' 

istediklerini elde etmek olabilir Ama zaten vardır

Eğer çalışıyorsanız bu yana

cevap

5

arama için bu lookahead normal ifadeler kullanabilirsiniz:

r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)' 

(?=[0-9]+) hemen öncesinde bakarak ikinci sayı varlığını iddia ama numarasını eşleştirerek iç regex işaretçi hareket etmez pozitif ileri yönlü olduğunu.

Ve değiştirilmesi için bunu kullanın:

r'\1 xby ' 

RegEx Demo

Kodu:

>>> pattern = r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)' 

>>> re.sub(pattern, r'\1 xby ', "2x4") 
'2 xby 4' 

>>> re.sub(pattern, r'\1 xby ', "2x4x12") 
'2 xby 4 xby 12' 
+1

Sanırım cevabı aldığımı düşündüğümde bunu daha çok seviyorum. Değiştirmeler, soldan sağa doğru yapıldığından bu yana almalısınız. – NickT

+1

Teşekkürler. Bunun ne yaptığını gevşek bir şekilde açıklayabilir misiniz? Doğru görünüyor, ama nedenini tam olarak anlamadım. – Ben

+1

Yanıtta lookahead bir açıklama ekledim. – anubhava

0

metinde karşı maç yeniden çalıştırmak daha iyi bir yolu olduğunu varsayalım regex tarafından dönüştürülmüş, gerçekten daha iyi bir yol yoktur.

Bir matematik problemini çözmek gibi bir şey, yapmak istediğinizde: (2 + 3) + 4, "(2 + 3)" değiştirebilmek için "5 + 4" i değiştirebilmeniz gerekir. "5" dizesi orijinal metninizde yer almıyor.

Yapmak istediğiniz şey, herhangi bir eşleşme için dizginizi sınamak ve daha fazla eşleşme bulunana kadar değiştirmelerinizi önceki sonuçlarınızda yeniden çalıştırmaya devam etmektir.

Düzenleme: Aynı zamanda, tekrarlama sayısı ve azalan uzunlukları için bunları çalıştırmak için birkaç düzenli ifade de oluşturabilirsiniz. Yani 2x3x5x2'yi 2x3x5 sonra 2x3'e bak.

1

Ne hakkında biraz farklı düşünerek, bir tek geçiş ile bu yaklaşım düşünüyorum o. Gerçekten yapmaya çalıştığınız şey x ile xby değiştirmektir - böylece rakamların sağ tarafını tüketmezseniz bütün dizeyi bir kez tarayabilirsiniz.

Bunun için bir ileriye dönük öneri öneririm. Temel olarak, değiştirdiğiniz şeyin basamaklarla geldiğini, ancak işlemdeki basamakları yemediğini doğrulayın. Bu gösterim (? = ...) - bkz. re docpage. Benim için

, şu var - regex derleme isteğe bağlıdır ve \ d genellikle tercih edilir olduğuna dikkat [0-9]:

pattern = re.compile(r"(\d+)\s*[xX\*]\s*(?=\d)") 
pattern.sub(r"\1 xby ", "2x4x12") 

'2 xby 4 xby 12' 

tek bir geçişte, bu tüm dizeyi işleyecek .

İlgili konular