Python, alfabe dışı tüm karakterleri dizeden kaldır


93

Bir python MapReduce kelime sayımı programı yazıyorum. Sorun şu ki, verilerde birçok alfabe dışı karakter var, bu yazıyı Python'daki bir dizeden alfanümerik karakterler dışında her şeyi çıkarıp regex kullanarak güzel bir çözüm gösteren buldum, ancak bunu nasıl uygulayacağımı bilmiyorum

def mapfn(k, v):
    print v
    import re, string 
    pattern = re.compile('[\W_]+')
    v = pattern.match(v)
    print v
    for w in v.split():
        yield w, 1

Korkarım rebu konuda kitaplığı ve hatta normal ifadeyi nasıl kullanacağımdan emin değilim . vAlfasayısal olmayan karakterler olmadan yeni satırı almak için normal ifade desenini gelen dizeye (bir kitabın satırı) nasıl uygulayacağımdan emin değilim .

Öneriler?


vbir kitabın tam bir satırıdır (özellikle moby dick), kelime kelime değil, kelime kelime gidiyorum. Yani bazı kelimelerin sonunda "," olabilir, bu nedenle "aşağılama" "aşağılama" ile eşleşmez.
KDecker


Lolx - benimle aynı görüşme öncesi evde egzersiz yaptınız mı? Moby Dick'te en çok kullanılan 50 kelimeyi bulun ve sıklıklarını bildirin. Bunu C ++,
IIRC'de

1
@Mawg Lisans "Bulut Bilişim" sınıfında bir alıştırmaydı.
KDecker

Yanıtlar:


130

Kullanım re.sub

import re

regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', 'ab3d*E')
#Out: 'abdE'

Alternatif olarak, yalnızca belirli bir karakter kümesini kaldırmak istiyorsanız (girişinizde kesme işareti uygun olabileceği için ...)

regex = re.compile('[,\.!?]') #etc.

Hmm, tam olarak izini sürebilirim, peki ya boşluklar hariç tüm alfanümerik olmayanları kaldırmak için model?
KDecker

1
Koleksiyon sınıfınıza bir alan eklemeniz yeterlidir. yani ^a-zA-Z sadece yerine^a-zA-Z
limasxgoesto0

Yeni satırlar için de endişelenmedikçe, bu durumda a-zA-Z \n. Her ikisini birden bir araya toplayacak, ancak bana istenen davranışı kullanan \wveya \Wvermeyen bir normal ifade bulmaya çalışıyorum . \nDurum buysa eklemeniz gerekebilir .
limasxgoesto0

Ahh, satırsonu karakteri. Sorunlarımın yattığı yer burası, sonuçlarımı verilen sonuçlarla karşılaştırıyordum ve hala kapalıydım. Sanırım bu benim sorunum! Teşekkürler // Hmm, satırsonu karakteriyle aynı sonuçlarla denedim, sanırım başka bir eksikim var .. // Duhhh ... Büyük ve küçük harf ... // Tüm yardımlar için teşekkürler, şimdi mükemmel çalışıyor!
KDecker

50

Normal ifadeyi kullanmamayı tercih ediyorsanız deneyebilirsiniz

''.join([i for i in s if i.isalpha()])

buna nasıl katılırım? ile ".join? yazdırma işlemleri yalnızca bir filtre nesnesi alır
PirateApp

1
Vay canına, işte aradığım buydu. Bu, kanji, hiragana, katakana vb. Dikkate alır. tebrikler
root163

34

Bu karakterleri kaldırmak için re.sub () işlevini kullanabilirsiniz:

>>> import re
>>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def")
'ABCabcdef'

re.sub (DESENİ EŞLEŞTİR, DİZEYİ DEĞİŞTİR, DİZE ARAMAK İÇİN)

  • "[^a-zA-Z]+" - a-zA-z OLMAYAN herhangi bir karakter grubunu arayın.
  • "" - Eşleşen karakterleri "" ile değiştirin

Bunun aksanlı harfleri de kaldıracağını unutmayın: ãâàáéèçõ, vb.
Brad Ahrens

19

Deneyin:

s = ''.join(filter(str.isalnum, s))

Bu, dizedeki her karakteri alacak, yalnızca alfasayısal olanları saklayacak ve onlardan bir dizi oluşturacaktır.


2
Bu cevap, çok daha fazla açıklama ve ilgili belgelere bağlantılar kullanabilir.
pdoherty926

4

En hızlı yöntem regex'tir

#Try with regex first
t0 = timeit.timeit("""
s = r2.sub('', st)

""", setup = """
import re
r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE)
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)

#Try with join method on filter
t0 = timeit.timeit("""
s = ''.join(filter(str.isalnum, st))

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""",
number = 1000000)
print(t0)

#Try with only join
t0 = timeit.timeit("""
s = ''.join(c for c in st if c.isalnum())

""", setup = """
st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+'
""", number = 1000000)
print(t0)


2.6002226710006653 Method 1 Regex
5.739747313000407 Method 2 Filter + Join
6.540099570000166 Method 3 Join

0

Belirli Unicode özellik sınıflarını eşleştirmeyi planlıyorsanız PyPi regexmodülünü kullanmanız önerilir . Bu kitaplığın özellikle büyük metinleri işleyerek daha kararlı olduğu ve çeşitli Python sürümlerinde tutarlı sonuçlar verdiği kanıtlanmıştır. Tek yapmanız gereken, onu güncel tutmaktır.

Yüklerseniz ( pip intall regexveya kullanarak pip3 install regex), kullanabilirsiniz

import regex
print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') )
// => ABCŁąćАбвdef

Unicode harfleri dışındaki 1 veya daha fazla karakterden oluşan tüm parçaları kaldırmak için text. Çevrimiçi bir Python demosuna bakın . "".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))Aynı sonucu almak için de kullanabilirsiniz .

Python'da re, herhangi bir Unicode harfiyle eşleştirmek için [^\W\d_]yapı kullanılabilir ( Herhangi bir unicode harfiyle eşleşir mi? ).

Dolayısıyla, harf olmayan tüm karakterleri kaldırmak için, tüm harfleri eşleştirebilir ve sonuçlara katılabilirsiniz:

result = "".join(re.findall(r'[^\W\d_]', text))

Veya eşleşenler dışındaki tüm karakterleri kaldırın [^\W\d_]:

result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)

Çevrimiçi normal ifade demosuna bakın . Ancak , çeşitli Python sürümlerinde tutarsız sonuçlar alabilirsiniz çünkü Unicode standardı gelişiyor ve eşleşen karakter seti \wPython sürümüne bağlı olacaktır. regexTutarlı sonuçlar elde etmek için PyPi kitaplığının kullanılması şiddetle tavsiye edilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.