2013-03-08 15 views
9

Mam następujący regularne zastąpienie wyrażenia:używać wyrażeń regularnych do zastąpienia nakładających podwzorów

input=re.sub(r"([a-zA-Z0-9])\s+([a-zA-Z0-9])" , r"\1*\2" , input) 

używam wyrażenia regularnego na strunie "3 a 5 b".

Wracam "3*a 5*b".

Myślę, że powinienem odzyskać "3*a*5*b".

W ten sposób moje substytucje wyrażenia regularnego interferują ze sobą.

Co mogę zrobić, aby uzyskać pożądany wynik, poza iteracyjnymi ciągami wyrażenia regularnego?

+0

input = re.sub ("", "*", input) - dostajesz to, co chcesz – PurityLake

+1

Nie, @PurityLake, nie ma. To spowodowałoby niepoprawne zamienniki w ciągu znaków '" 3/a 5! B "' – Richard

+0

Przepraszam, że działałem tylko na podanych informacjach, myślałem tylko, że chcesz zastąpić spacje znakiem "*". – PurityLake

Odpowiedz

18

Użyć lookahead assertion, (?=...), tak aby nie jeść drugiego wzoru:

In [33]: re.sub(r"([a-zA-Z0-9])\s+(?=[a-zA-Z0-9])" , r"\1*" , '3 a 5 b') 
Out[33]: '3*a*5*b' 

In [32]: re.sub(r"([a-zA-Z0-9])\s+(?=[a-zA-Z0-9])" , r"\1*" , "3 /a 5! b") 
Out[32]: '3 /a*5! b' 
+0

@StevenRumbalski: Dzięki! – unutbu

+0

I ** pamiętaj **, kiedy zmienisz (grupę) na (? = = Poprzedni), grupa (grupa) już nie istnieje. Dlatego nie ma \ 2 w tej odpowiedzi. –

1

Wyrażenia regularne nie zawsze są najlepszym narzędziem do pracy podczas używania Pythona. Dla opisujesz powyżej przypadku, Python oferuje znacznie prostszy, bardziej czytelny i bardziej linkujących metody:

>>> s = "3 a 5 b" 
>>> '*'.join(s.split()) 
'3*a*5*b' 
+0

Dobra odpowiedź - niestety, O.P. zaktualizował swoje potrzeby w komentarzach. To jednak odpowiada na pierwotne pytanie. – jsbueno

+0

Klasa znaków "[a-zA-Z0-9]" wyraźnie wyklucza zastąpienie przestrzeni, gdy mieści się ona pomiędzy różnymi postaciami, podczas gdy sugerowana odpowiedź nie. – Richard

+0

Ach tak, post został zaktualizowany. Widzę. Biorąc pod uwagę nowe informacje, stwierdzenie z wyprzedzeniem rzeczywiście brzmi jak najlepsza odpowiedź dla mnie. –

Powiązane problemy