Dizeden tüm özel karakterleri, noktalama işaretlerini ve boşlukları kaldır


236

Ben sadece harf ve rakam var böylece bir dizeden tüm özel karakterler, noktalama işaretleri ve boşlukları kaldırmak gerekiyor.

Yanıtlar:


351

Bu normal ifade olmadan yapılabilir:

>>> string = "Special $#! characters   spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'

Şunları kullanabilirsiniz str.isalnum:

S.isalnum() -> bool

Return True if all characters in S are alphanumeric
and there is at least one character in S, False otherwise.

Regex kullanmakta ısrar ederseniz, diğer çözümler işe yarayacaktır. Ancak, normal bir ifade kullanmadan yapılabiliyorsa, bunun için en iyi yolun bu olduğunu unutmayın.


7
Normal kural olarak normal ifadeyi kullanmamanın nedeni nedir?
Chris Dutrow

@ChrisDutrow regex, python dizesi yerleşik işlevlerinden daha yavaş
Diego Navarro

Bu yalnızca dize unicode olduğunda çalışır . Aksi takdirde, 'str' nesnesinin 'isalnum' 'isnumeric' niteliği olmadığı gibi şikayetçi olur.
NeoJi

10
@DiegoNavarro bu doğru değil, hem isalnum()regex sürümlerini
kıyasladım

2
Ayrıca: "8 bit dizeler için bu yöntem yerel ayara bağlıdır."! Böylece regex alternatif kesinlikle daha iyi!
Antti Haapala

232

Harf veya sayı olmayan bir karakter dizisiyle eşleşecek normal ifade:

[^A-Za-z0-9]+

Regex ikamesi yapmak için Python komutu:

re.sub('[^A-Za-z0-9]+', '', mystring)

10
ÖPÜCÜK: Sade Aptal Olsun! Normal olmayan çözümlerden daha kısa ve okunması daha kolaydır ve aynı zamanda daha hızlı olabilir. (Ancak, +verimliliğini biraz artırmak için bir nicelleştirici ekleyeceğim .)
ridgerunner

1
Bu aynı zamanda kelimeler arasındaki boşlukları kaldırır, "harika bir yer" -> "harika bir yer". Nasıl önlenir?
Reihan_amn

5
@Reihan_amn Normal ifade için bir boşluk ekleyin, böylece olur:[^A-Za-z0-9 ]+
ostroon

1
@ andy-white Lütfen cevabı normal ifadeye ekleyebilir misiniz? Uzay özel bir karakter değil ...
Ufos

3
Sanırım bu á , ö , ñ gibi diğer dillerde değiştirilmiş karakterlerle çalışmaz . Haklı mıyım? Eğer öyleyse, bunun için normal ifade nasıl olurdu?
HuLu ViCa

50

Daha kısa yol:

import re
cleanString = re.sub('\W+','', string )

Kelimeler ve sayılar arasında boşluk olmasını istiyorsanız '' ile '' yerine


3
Bunun dışında _ \ \ içinde ve bu soru bağlamında özel bir karakter.
kkurian

Bağlama göre değişir - alt çizgi, dosya adları ve diğer tanımlayıcılar için, onu özel bir karakter olarak değil, daha ziyade sterilize edilmiş bir alan olarak ele aldığım noktaya kadar çok yararlıdır.
Echelon

1
r'\W+'- biraz konu dışı (ve çok bilgiçlik) ama tüm regex modellerinin ham teller
Bob Stein

2
Bu yordam alt çizgiyi (_) özel bir karakter olarak ele almaz.
Md. Sabbir Ahmed

30

Bunu gördükten sonra, hangi cevapların en kısa sürede yürütüldüğünü öğrenerek sağlanan cevapları genişletmekle ilgilenmiştim, bu yüzden geçtim ve önerilen bazı cevapları timeitörnek dizelerden ikisine karşı kontrol ettim :

  • string1 = 'Special $#! characters spaces 888323'
  • string2 = 'how much for the maple syrup? $20.99? That s ricidulous!!!'

örnek 1

'.join(e for e in string if e.isalnum())

  • string1 - Sonuç: 10.7061979771
  • string2 - Sonuç: 7.78372597694

ÖRNEK 2

import re re.sub('[^A-Za-z0-9]+', '', string)

  • string1 - Sonuç: 7.10785102844
  • string2 - Sonuç: 4.12814903259

ÖRNEK 3

import re re.sub('\W+','', string)

  • string1 - Sonuç: 3.11899876595
  • string2 - Sonuç: 2.78014397621

Yukarıdaki sonuçlar ortalamadan en düşük getirili sonucun bir ürünüdür: repeat(3, 2000000)

Örnek 3 , Örnek 1'den 3 kat daha hızlı olabilir .


@kkurian Cevabımın başlangıcını okursanız, bu sadece yukarıda önerilen çözümlerin bir karşılaştırmasıdır. Kaynak cevap için yorum yapmak isteyebilirsiniz ... stackoverflow.com/a/25183802/2560922
mbeacom

Oh, bununla nereye gittiğini anlıyorum. Bitti!
kkurian

1
Büyük korpusla uğraşırken Örnek 3'ü dikkate almalıdır.
HARSH NILESH PATHAK

Geçerli! Kaydettiğiniz için teşekkürler.
mbeacom

cevabımı karşılaştırabilir misin''.join([*filter(str.isalnum, string)])
Grijesh Chauhan

22

Python 2. *

Bence sadece filter(str.isalnum, string)çalışıyor

In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'

Python 3. *

Python3'te, filter( )işlev yinelenebilir bir nesne döndürür (yukarıdakinin aksine dize yerine). İtertable bir dize almak için geri katılmak gerekir:

''.join(filter(str.isalnum, string)) 

veya listbirleştirme kullanımında geçmek için ( emin değilim ama biraz hızlı olabilir )

''.join([*filter(str.isalnum, string)])

not: açma işlemi Python'dan[*args] geçerli => 3.5


4
@Alexey python3 olarak, doğru map, filterve reduce bunun yerine döner itertable nesne. Hala Python3 + ' ''.join(filter(str.isalnum, string)) da ''.join([*filter(str.isalnum, string)])kabul edilen cevabı tercih ederim (veya birleştirme kullanımında listeyi geçmeyi ).
Grijesh Chauhan

En azından okumak ''.join(filter(str.isalnum, string))için bir gelişme olduğundan emin değilim filter(str.isalnum, string). Bunu yapmak için gerçekten Pythreenic mi (evet, bunu kullanabilirsiniz)?
Proletariat

1
@TheProletariat Mesele sadecefilter(str.isalnum, string)filter( ) Python- 2'de olduğu gibi argüman türü yerine Python-3'de yineleyici gibi Python3'te dize döndürmüyor . +
Grijesh Chauhan

@GrijeshChauhan, yanıtınızı hem Python2 hem de Python3 önerilerinizi içerecek şekilde güncellemeniz gerektiğini düşünüyorum.
mwfearnley

18
#!/usr/bin/python
import re

strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr

daha özel bir karakter ekleyebilirsiniz ve bunun yerine '' ifadesi kaldırılacak hiçbir şey ifade etmez.


16

Normal ifadeyi kullanan herkesten farklı olarak, istemediğimi açıkça numaralandırmak yerine, istediğim olmayan her karakteri hariç tutmaya çalışırdım.

Örneğin, yalnızca 'a'dan z'ye (büyük ve küçük harf) ve sayılardan karakterler istiyorsanız, diğer her şeyi hariç tutarım:

import re
s = re.sub(r"[^a-zA-Z0-9]","",s)

Bu, "sayı olmayan her karakteri veya 'a'dan z'ye veya' A'dan Z'ye kadar olan bir karakteri boş bir dizeyle değiştir" anlamına gelir.

Aslında, ^regex'inizin ilk yerine özel karakteri eklerseniz , olumsuzlamayı alırsınız.

Ekstra ipucu: ayrıca sonucu küçük harflerle yazmanız gerekiyorsa , şu anda büyük harf bulamadığınız sürece normal ifadeyi daha da hızlı ve kolay hale getirebilirsiniz.

import re
s = re.sub(r"[^a-z0-9]","",s.lower())

9

Normal ifade kullanmak istediğinizi ve 2to3 için hazır olan Unicode-cognizant 2.x kodunu istediğinizi / ihtiyacınız olduğunu varsayarsak:

>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>

7
s = re.sub(r"[-()\"#/@;:<>{}`+=~|.!?,]", "", s)

6

En genel yaklaşım, her bir karakteri sınıflandıran unicodedata tablosunun 'kategorilerini' kullanmaktır. Aşağıdaki kod, yalnızca kategorilerine göre yazdırılabilir karakterleri filtreler:

import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien

PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))

def filter_non_printable(s):
    result = []
    ws_last = False
    for c in s:
        c = unicodedata.category(c) in PRINTABLE and c or u'#'
        result.append(c)
    return u''.join(result).replace(u'#', u' ')

İlgili tüm kategoriler için yukarıdaki URL'ye bakın. Tabii ki noktalama kategorilerine göre de filtreleyebilirsiniz.


$Her satırın sonunda ne var ?
John Machin

Kopyala ve yapıştır sorunu varsa, düzeltmeniz gerekir mi?
Olli

5

string.punctuation aşağıdaki karakterleri içerir:

'"# $% & \! '() * +, - / :; <=> @ [\] ^ _`.? {|} ~'

Noktalama işaretlerini boş değerlerle eşleştirmek için translate ve maketrans işlevlerini kullanabilirsiniz (değiştir)

import string

'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))

Çıktı:

'This is A test'

4

Çeviri kullan:

import string

def clean(instr):
    return instr.translate(None, string.punctuation + ' ')

Uyarı: Yalnızca ascii dizelerinde çalışır.


Sürüm farkı? Ben olsun TypeError: translate() takes exactly one argument (2 given)py3.4 ile
mat Wilkie'ye

1
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the 

çift ​​tırnak işaretleri ile aynı. "" "

# if we need to count the word python that ends with or without ',' or '.' at end

count = 0
for i in text:
    if i.endswith("."):
        text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
    count += 1
print("The count of Python : ", text.count("python"))

0
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)

ve sonucunu şu şekilde göreceksin:

'askhnlaskdjalsdk


4
bekle .... sen ithal reama hiç kullanmadın. Sizin replacekriterler yalnızca bu dize için çalışır. Dizeniz ne olacak abc = "askhnl#$%!askdjalsdk"? Desenden başka bir şey üzerinde çalışacağını sanmıyorum #$%. Tweak
isteyebilirsiniz

0

Noktalama İşaretlerini, Sayıları ve Özel Karakterleri Kaldırma

Misal :-

resim açıklamasını buraya girin

kod

combi['tidy_tweet'] = combi['tidy_tweet'].str.replace("[^a-zA-Z#]", " ") 

Sonuç:- resim açıklamasını buraya girin

Teşekkürler :)


0

Özel karakterler (Almanca "Umlaute" as ü,, ägibi ö) içeren Almanca, İspanyolca, Danca, Fransızca gibi diğer diller için bunları normal ifade arama dizesine eklemeniz yeterlidir:

Almanca için örnek:

re.sub('[^A-ZÜÖÄa-z0-9]+', '', mystring)
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.