Python, hapus semua karakter non-alfabet dari string


90

Saya sedang menulis program penghitungan kata MapReduce python. Masalahnya adalah bahwa ada banyak karakter non-alfabet berserakan dalam data, saya telah menemukan posting ini Menghapus semuanya kecuali karakter alfanumerik dari string dengan Python yang menunjukkan solusi yang bagus menggunakan regex, tetapi saya tidak yakin bagaimana cara menerapkannya

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

Saya khawatir saya tidak yakin bagaimana menggunakan perpustakaan reatau bahkan regex dalam hal ini. Saya tidak yakin bagaimana menerapkan pola regex ke string masuk (baris buku) vdengan benar untuk mengambil baris baru tanpa karakter non-alfanumerik.

Saran?


vadalah keseluruhan baris dari sebuah buku (khususnya moby dick), saya akan kata demi kata bukan karakter demi karakter. Jadi beberapa kata mungkin memiliki "," pada akhirnya jadi "penghinaan," tidak dipetakan dengan "penghinaan".
KDecker


Lolx - apakah Anda melakukan senam pra-wawancara yang sama dengan saya? Temukan 50 kata yang paling sering digunakan di Moby Dick dan laporkan frekuensinya. Saya melakukannya di C ++, IIRC
Mawg mengatakan memulihkan Monica

1
@Mawg Itu adalah latihan di kelas "Cloud Computing" saya.
KDecker

Jawaban:


128

Menggunakan 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'

Alternatifnya, jika Anda hanya ingin menghapus sekumpulan karakter tertentu (sebagai apostrof mungkin baik-baik saja dalam masukan Anda ...)

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

Hmm, saya bisa melacaknya, tapi bagaimana dengan pola untuk menghapus semua spasi non-alfanumerik?
KDecker

1
Cukup tambahkan ruang ke kelas koleksi Anda. yaitu, ^a-zA-Z bukannya hanya^a-zA-Z
limasxgoesto0

Kecuali jika Anda juga khawatir tentang baris baru, dalam hal ini a-zA-Z \n. Saya mencoba menemukan regex yang akan menggabungkan keduanya menjadi satu tetapi menggunakan \watau \Wtidak memberi saya perilaku yang diinginkan. Anda mungkin perlu menambahkan \njika itu masalahnya.
limasxgoesto0

Ahh, karakter baris baru. Di situlah letak masalah saya, saya membandingkan hasil saya dengan hasil yang diberikan dan saya masih pergi. Saya pikir itu masalah saya! Terima kasih // Hmm, saya mencobanya dengan karakter baris baru hasil yang sama, saya rasa ada yang lain yang saya lewatkan .. // Duhhh ... Huruf besar dan kecil ... // Terima kasih atas semua bantuannya, berfungsi dengan baik sekarang!
KDecker

48

Jika Anda memilih untuk tidak menggunakan regex, Anda dapat mencobanya

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

bagaimana cara bergabung dengan ini? dengan '' .join? pencetakan hanya mendapat objek filter
PirateApp

Wow, inilah yang saya cari. Ini memperhitungkan kanji, hiragana, katakana, dll. kudos
root163

34

Anda dapat menggunakan fungsi re.sub () untuk menghapus karakter ini:

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

re.sub (POLA PERTANDINGAN, GANTI STRING, STRING UNTUK MENELUSURI)

  • "[^a-zA-Z]+" - cari kelompok karakter yang BUKAN a-zA-z.
  • "" - Ganti karakter yang cocok dengan ""

Perhatikan bahwa ini juga akan menghapus huruf beraksen: ãâàáéèçõ, dll.
Brad Ahrens

19

Mencoba:

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

Ini akan mengambil setiap karakter dari string, hanya menyimpan karakter alfanumerik dan membangun string kembali darinya.


1
Jawaban ini membutuhkan lebih banyak penjelasan dan tautan ke dokumentasi yang relevan.
pdoherty926

4

Metode tercepat adalah regex

#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

Disarankan untuk menggunakan modul PyPiregex jika Anda berencana untuk mencocokkan kelas properti Unicode tertentu. Library ini juga terbukti lebih stabil, terutama menangani teks berukuran besar, dan memberikan hasil yang konsisten di berbagai versi Python. Yang perlu Anda lakukan adalah menjaganya tetap mutakhir.

Jika Anda menginstalnya (menggunakan pip intall regexatau pip3 install regex), Anda dapat menggunakan

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

untuk menghapus semua potongan dari 1 atau lebih karakter selain huruf Unicode dari text. Lihat demo Python online . Anda juga dapat menggunakan "".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))untuk mendapatkan hasil yang sama.

Di Python re, untuk mencocokkan huruf Unicode apa pun, seseorang dapat menggunakan [^\W\d_]konstruksi ( Cocokkan huruf unicode apa saja? ).

Jadi, untuk menghapus semua karakter bukan huruf, Anda dapat mencocokkan semua huruf dan menggabungkan hasilnya:

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

Atau, hapus semua karakter selain yang cocok dengan [^\W\d_]:

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

Lihat demo regex online . Namun , Anda mungkin mendapatkan hasil yang tidak konsisten di berbagai versi Python karena standar Unicode sedang berkembang, dan kumpulan karakter yang cocok \wakan bergantung pada versi Python. Menggunakan regexpustaka PyPi sangat disarankan untuk mendapatkan hasil yang konsisten.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.