2016-01-01 13 views
7

Bir cümledeki negatif bağlamları işaretlemem gerekiyor. aşağıdaki gibi algoritma gider:Python'da belirli bir normal ifadeyle eşleşen metin nasıl değiştirilir?

  1. bir olumsuz kimse (değil/asla/değil/yapamaz/vs)
  2. bir madde biten noktalama Algılama Algılama (;:.!?)
  3. ekle _NEG bu arasındaki tüm kelimeleri.

Şimdi, tüm bu oluşumları ortaya çıkarmak için bir normal ifade tanımlamış:

def replacenegation(text): 
    match=re.search(r"((\b(never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint)\b)|\b\w+n't\b)((?![.:;!?]).)*[.:;!?\b]", text) 
    if match: 
     s=match.group() 
     print s 
     news="" 
     wlist=re.split(r"[.:;!? ]" , s) 
     wlist=wlist[1:] 
     print wlist 
     for w in wlist: 
      if w: 
       news=news+" "+w+"_NEG" 
     print news 

Ben algılamak ve eşleştirilmiş grup yerini alabilir. Ancak, bu işlemden sonra tüm cümleyi nasıl yeniden oluşturacağımı bilmiyorum. Ayrıca birden fazla eşleşme için match.groups() bana yanlış çıktı verir.

Örneğin benim giriş cümlesi ise:

I don't like you at all; I should not let you know my happiest secret. 

Çıktı olmalıdır:

I don't like_NEG you_NEG at_NEG all_NEG ; I should not let_NEG you_NEG know_NEG my_NEG happiest_NEG secret_NEG . 

Bunu nasıl yapacağım?

cevap

4

Öncelikle negatif bir karakter sınıfına (?![.:;!?]).)* olumsuz bakışını değiştirmek daha iyi olur.

([^.:;!?]*) 

O zaman döner olacak, hiçbiri yakalama grubu kullanın ve 3 yakalama grup tarafından onu çevreleyen çünkü negatif kelimeler için ekstra olanları kaldırmak gerekir not gibi olumsuz kelimelerin 3 maç.

>>> regex =re.compile(r"((?:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint)\b|\b\w+n't\b)([^.:;!?]*)([.:;!?\b])") 
>>> 
>>> regex.findall(s) 
[("don't", ' like you at all', ';'), ('not', ' let you know my happiest secret', '.')] 

Yoksa ikamesi olarak bir lambda fonksiyonu ile re.sub kullanabilirsiniz kelimeleri değiştirilmesi için: noktalama yakalamak için ihtiyacınız olduğunu

>>> regex.sub(lambda x:x.group(1)+' '+' '.join([i+'_NEG' for i in x.group(2).split()])+x.group(3) ,s) 
"I don't like_NEG you_NEG at_NEG all_NEG; I should not let_NEG you_NEG know_NEG my_NEG happiest_NEG secret_NEG." 

Not sonra tüm eşleşmeleri bulmak için re.findall() kullanabilirsiniz onu da bir yakalama grubuna koymak. Daha sonra, düzenlemeden sonra re.sub() içinde cümlelerinizin sonuna ekleyebilirsiniz.

+1

Bu mükemmel çalışır! Noktalamalara gelince, metin üzerinde basit bir belirteci de kullanabilirim, çünkü yine de onları ve ifadeleri birbirinden ayırmam gerekecek. Teşekkürler! – Avijit

İlgili konular