2014-09-02 42 views
7

Ben şu cümleyi olduğunu varsayalım:belirli kelimeleri tüm tekrarlarını değiştirmek

bean likes to sell his beans 

ve ben başka deyişle belirli kelime tüm tekrarlarını değiştirmek istiyor. Örneğin, bean - robert ve beans - cars.

Bu durumda beans değerini roberts olarak değiştireceğinden str.replace10 kullanamıyorum.

>>> "bean likes to sell his beans".replace("bean","robert") 
'robert likes to sell his roberts' 

Yalnızca tüm sözcükleri değiştirmem gerekiyor, kelimenin diğer sözcükteki oluşumlarını değil. Bunu normal ifadeler kullanarak gerçekleştirebileceğimi düşünüyorum, ancak bunu nasıl yapacağımı bilmiyorum.

+0

yapabildin 'bölünmüş()' ben o gerçek görevde bu şekilde yapamaz ilk kelimelere metin – cmd

cevap

14

: Aslında bu şekilde çalışır

İşte
import re 

sentence = 'bean likes to sell his beans' 

sentence = re.sub(r'\bbean\b', 'robert', sentence) 
# 'robert likes to sell his beans' 

'fasulye' ('Roberts' kadar) değişmez, çünkü 'ın 'Sonunda kelimeler arasında bir sınır yoktur: \b boş dizeyle eşleşir, ancak kelimenin başına sadece. şeyiyle

ikinci yedek: Bir seferde her kelimeyi tek değiştirin

sentence = re.sub(r'\bbeans\b', 'cars', sentence) 
# 'robert likes to sell his cars' 
+1

Neden parantez tanımsız? – Jerry

+1

Parantezlerin gerekli olmadığına inanıyorum, sadece regex'i daha okunabilir hale getirdiler (en azından benim için). –

+0

Bazı nedenlerden dolayı bu durum ABD – Kahless

-1
"bean likes to sell his beans".replace("beans", "cars").replace("bean", "robert") 

"Fasulye" nin tüm örneklerini "arabalar" ve "fasulye" ile "robert" ile değiştirir. Bu, .replace(), özgün bir dizenin değiştirilmiş bir örneğini döndürdüğü için çalışır. Bu şekilde aşamada düşünebilirsiniz. Eğer düzenli ifade kullanırsanız, \b ile kelime sınırlarını belirtebilirsiniz

>>> first_string = "bean likes to sell his beans" 
>>> second_string = first_string.replace("beans", "cars") 
>>> third_string = second_string.replace("bean", "robert") 
>>> print(first_string, second_string, third_string) 

('bean likes to sell his beans', 'bean likes to sell his cars', 
    'robert likes to sell his cars') 
+0

, bu sırası değiştirmeleri nedeniyle – FrozenHeart

3

, sen kelimeler defalarca değiştirmesi (ve istediğini elde değil) olabilir. Bunu önlemek için, bir işlev veya lambda kullanabilirsiniz:

d = {'bean':'robert', 'beans':'cars'} 
str_in = 'bean likes to sell his beans' 
str_out = re.sub(r'\b(\w+)\b', lambda m:d.get(m.group(1), m.group(1)), str_in) 

O yol, bir zamanlar beanrobert ile değiştirilir, (robert kelime senin girdi listesinde de bile) tekrar modifiye edilmeyecektir.

georg tarafından önerilen şekilde, bu cevabı dict.get(key, default_value) ile düzenledim. Bildiğim

str_out = re.sub(r'\b(%s)\b' % '|'.join(d.keys()), lambda m:d.get(m.group(1), m.group(1)), str_in) 
+0

'un tüm örneklerini almıyor gibi gözüküyor. Bunu daha basit (ve daha hızlı) yapabilmeli ve eğer '\ bbeans?' regex ve lambda 'm.group (0)' (tüm maç için) kullanın. – Jerry

+0

Bunun genel olarak yeterli olmasını istiyorum, bu nedenle 1 regex herhangi bir giriş metni + değiştirilecek herhangi bir kelime listesiyle baş edebilir. Yani ben fasulyemde "fasülyeler" istemiyorum. – seb

+0

Anladım. Sadece her bir kelimeyi kontrol edeceği ve bunun ana darboğaz olduğuna inanıyorum. – Jerry

-1

onun uzun zaman oldu ama bu çok daha şık görünüyor mu: (aynı zamanda georg önerdiği) Alternatif çözüm? :

reduce(lambda x,y : re.sub('\\b('+y[0]+')\\b',y[1],x) ,[("bean","robert"),("beans","cars")],"bean likes to sell his beans") 
İlgili konular