De beste manier om interpunctie uit een tekenreeks te verwijderen

Het lijkt erop dat er een eenvoudigere manier moet zijn dan:

import string
s = "string. With. Punctuation?" # Sample string 
out = s.translate(string.maketrans("",""), string.punctuation)

Is er?


Antwoord 1, autoriteit 100%

Vanuit een efficiëntieperspectief gaat u niet verslaan

s.translate(None, string.punctuation)

Gebruik voor hogere versies van Python de volgende code:

s.translate(str.maketrans('', '', string.punctuation))

Het voert onbewerkte tekenreeksbewerkingen uit in C met een opzoektabel – er is niet veel dat dat kan verslaan, behalve het schrijven van uw eigen C-code.

Als snelheid geen probleem is, is een andere optie:

exclude = set(string.punctuation)
s = ''.join(ch for ch in s if ch not in exclude)

Dit is sneller dan s.replace met elke char, maar zal niet zo goed presteren als niet-pure python-benaderingen zoals regexes of string.translate, zoals je kunt zien aan de onderstaande timings. Voor dit soort problemen loont het om het op een zo laag mogelijk niveau te doen.

Timingcode:

import re, string, timeit
s = "string. With. Punctuation"
exclude = set(string.punctuation)
table = string.maketrans("","")
regex = re.compile('[%s]' % re.escape(string.punctuation))
def test_set(s):
    return ''.join(ch for ch in s if ch not in exclude)
def test_re(s):  # From Vinko's solution, with fix.
    return regex.sub('', s)
def test_trans(s):
    return s.translate(table, string.punctuation)
def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s
print "sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000)
print "regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000)
print "translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000)
print "replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000)

Dit geeft de volgende resultaten:

sets      : 19.8566138744
regex     : 6.86155414581
translate : 2.12455511093
replace   : 28.4436721802

Antwoord 2, autoriteit 16%

Reguliere uitdrukkingen zijn eenvoudig genoeg, als u ze kent.

import re
s = "string. With. Punctuation?"
s = re.sub(r'[^\w\s]','',s)

Antwoord 3, autoriteit 7%

Voor het gebruiksgemak vat ik de opmerking samen van het stripen van interpunctietekens van een tekenreeks in zowel Python 2 als Python 3. Raadpleeg andere antwoorden voor de gedetailleerde beschrijving.


Python 2

import string
s = "string. With. Punctuation?"
table = string.maketrans("","")
new_s = s.translate(table, string.punctuation)      # Output: string without punctuation

Python 3

import string
s = "string. With. Punctuation?"
table = str.maketrans(dict.fromkeys(string.punctuation))  # OR {key: None for key in string.punctuation}
new_s = s.translate(table)                          # Output: string without punctuation

Antwoord 4, autoriteit 5%

myString.translate(None, string.punctuation)

Antwoord 5, autoriteit 3%

Ik gebruik meestal zoiets als dit:

>>> s = "string. With. Punctuation?" # Sample string
>>> import string
>>> for c in string.punctuation:
...     s= s.replace(c,"")
...
>>> s
'string With Punctuation'

Antwoord 6, autoriteit 3%

string.punctuation is alleen in ASCII! Een meer correcte (maar ook veel langzamere) manier is om de unicodedata-module te gebruiken:

# -*- coding: utf-8 -*-
from unicodedata import category
s = u'String — with -  «punctation »...'
s = ''.join(ch for ch in s if category(ch)[0] != 'P')
print 'stripped', s

Je kunt ook andere typen karakters generaliseren en strippen:

''.join(ch for ch in s if category(ch)[0] not in 'SP')

Het zal ook tekens zoals ~*+§$ verwijderen, wat al dan niet “interpunctietekens” kan zijn, afhankelijk van iemands standpunt.


Antwoord 7, autoriteit 3%

Niet per se eenvoudiger, maar op een andere manier, als je meer bekend bent met de re-familie.

import re, string
s = "string. With. Punctuation?" # Sample string 
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)

Antwoord 8

Voor Python 3 str of Python 2 unicode waarden, str.translate() heeft alleen een woordenboek nodig; codepunten (gehele getallen) worden opgezocht in die toewijzing en alles dat is toegewezen aan None wordt verwijderd.

Om dan (sommige?) leestekens te verwijderen, gebruik:

import string
remove_punct_map = dict.fromkeys(map(ord, string.punctuation))
s.translate(remove_punct_map)

De klasse dict.fromkeys() methode maakt het triviaal om de toewijzing te maken, waarbij alle waarden worden ingesteld op None op basis van de volgorde van de toetsen.

Om alle leestekens te verwijderen, niet alleen ASCII-interpunctietekens, moet uw tabel iets groter zijn; zie J.F. Sebastian’s antwoord (Python 3-versie):

import unicodedata
import sys
remove_punct_map = dict.fromkeys(i for i in range(sys.maxunicode)
                                 if unicodedata.category(chr(i)).startswith('P'))

Antwoord 9

string.punctuation mist veel leestekens die in de echte wereld veel worden gebruikt. Wat dacht je van een oplossing die werkt voor niet-ASCII-interpunctie?

import regex
s = u"string. With. Some?Really Weird?Non?ASCII? ?(Punctuation)??"
remove = regex.compile(ur'[\p{C}|\p{M}|\p{P}|\p{S}|\p{Z}]+', regex.UNICODE)
remove.sub(u" ", s).strip()

Persoonlijk geloof ik dat dit de beste manier is om interpunctie uit een tekenreeks in Python te verwijderen, omdat:

  • Het verwijdert alle Unicode-interpunctie
  • Het is gemakkelijk aan te passen, b.v. je kunt de \{S} verwijderen als je interpunctie wilt verwijderen, maar symbolen zoals $ wilt behouden.
  • Je kunt heel specifiek zijn over wat je wilt behouden en wat je wilt verwijderen, bijvoorbeeld \{Pd} verwijdert alleen streepjes.
  • Deze regex normaliseert ook de witruimte. Het wijst tabbladen, regelterugloop en andere eigenaardigheden toe aan mooie, enkele spaties.

Dit maakt gebruik van Unicode-tekeneigenschappen, waar meer over kunt lezen op Wikipedia.


Antwoord 10

Hier is een one-liner voor Python 3.5:

import string
"l*ots! o(f. p@u)n[c}t]u[a'ti\"on#$^?/".translate(str.maketrans({a:None for a in string.punctuation}))

Antwoord 11

Ik heb dit antwoord nog niet gezien. Gebruik gewoon een regex; het verwijdert alle tekens behalve woordtekens (\w) en cijfertekens (\d), gevolgd door een spatie (\s):

import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(ur'[^\w\d\s]+', '', s)

Antwoord 12

Dit is misschien niet de beste oplossing, maar dit is hoe ik het deed.

import string
f = lambda x: ''.join([i for i in x if i not in string.punctuation])

Antwoord 13

import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(r'[^a-zA-Z0-9\s]', '', s)

Antwoord 14

Hier is een functie die ik heb geschreven. Het is niet erg efficiënt, maar het is eenvoudig en je kunt elk gewenst leesteken toevoegen of verwijderen:

def stripPunc(wordList):
    """Strips punctuation from list of words"""
    puncList = [".",";",":","!","?","/","\\",",","#","@","$","&",")","(","\""]
    for punc in puncList:
        for word in wordList:
            wordList=[word.replace(punc,'') for word in wordList]
    return wordList

Antwoord 15

Als een update heb ik het @Brian-voorbeeld in Python 3 herschreven en er wijzigingen in aangebracht om de regex-compileerstap binnen de functie te verplaatsen. Mijn gedachte hier was om elke stap te timen die nodig was om de functie te laten werken. Misschien gebruikt u gedistribueerd computergebruik en kunt u het regex-object niet delen tussen uw werknemers en moet u bij elke werknemer de stap re.compile uitvoeren. Ik was ook nieuwsgierig om twee verschillende implementaties van maketrans voor Python 3 te timen

table = str.maketrans({key: None for key in string.punctuation})

vs

table = str.maketrans('', '', string.punctuation)

Bovendien heb ik een andere methode toegevoegd om set te gebruiken, waarbij ik gebruik maak van de intersectiefunctie om het aantal iteraties te verminderen.

Dit is de volledige code:

import re, string, timeit
s = "string. With. Punctuation"
def test_set(s):
    exclude = set(string.punctuation)
    return ''.join(ch for ch in s if ch not in exclude)
def test_set2(s):
    _punctuation = set(string.punctuation)
    for punct in set(s).intersection(_punctuation):
        s = s.replace(punct, ' ')
    return ' '.join(s.split())
def test_re(s):  # From Vinko's solution, with fix.
    regex = re.compile('[%s]' % re.escape(string.punctuation))
    return regex.sub('', s)
def test_trans(s):
    table = str.maketrans({key: None for key in string.punctuation})
    return s.translate(table)
def test_trans2(s):
    table = str.maketrans('', '', string.punctuation)
    return(s.translate(table))
def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s
print("sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000))
print("sets2      :",timeit.Timer('f(s)', 'from __main__ import s,test_set2 as f').timeit(1000000))
print("regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000))
print("translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000))
print("translate2 :",timeit.Timer('f(s)', 'from __main__ import s,test_trans2 as f').timeit(1000000))
print("replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000))

Dit zijn mijn resultaten:

sets      : 3.1830138750374317
sets2      : 2.189873124472797
regex     : 7.142953420989215
translate : 4.243278483860195
translate2 : 2.427158243022859
replace   : 4.579746678471565

Antwoord 16

>>> s = "string. With. Punctuation?"
>>> s = re.sub(r'[^\w\s]','',s)
>>> re.split(r'\s*', s)
['string', 'With', 'Punctuation']

Antwoord 17

Hier is een oplossing zonder regex.

import string
input_text = "!where??and!!or$$then:)"
punctuation_replacer = string.maketrans(string.punctuation, ' '*len(string.punctuation))    
print ' '.join(input_text.translate(punctuation_replacer).split()).strip()
Output>> where and or then
  • Vervangt de leestekens door spaties
  • Vervang meerdere spaties tussen woorden door een enkele spatie
  • Verwijder de volgspaties, indien aanwezig met
    strip()

Antwoord 18

Een one-liner kan nuttig zijn in niet erg strikte gevallen:

''.join([c for c in s if c.isalnum() or c.isspace()])

Antwoord 19

Waarom gebruikt niemand van jullie dit?

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

Te langzaam?


Antwoord 20

with open('one.txt','r')as myFile:
    str1=myFile.read()
    print(str1)
    punctuation = ['(', ')', '?', ':', ';', ',', '.', '!', '/', '"', "'"] 
for i in punctuation:
        str1 = str1.replace(i," ") 
        myList=[]
        myList.extend(str1.split(" "))
print (str1) 
for i in myList:
    print(i,end='\n')
    print ("____________")

Antwoord 21

Hier is nog een andere gemakkelijke manier om dit te doen met RegEx

import re
punct = re.compile(r'(\w+)')
sentence = 'This ! is : a # sample $ sentence.' # Text with punctuation
tokenized = [m.group() for m in punct.finditer(sentence)]
sentence = ' '.join(tokenized)
print(sentence) 
'This is a sample sentence'

Antwoord 22

Probeer dat eens 🙂

regex.sub(r'\p{P}','', s)

Antwoord 23

# FIRST METHOD
# Storing all punctuations in a variable    
punctuation='!?,.:;"\')(_-'
newstring ='' # Creating empty string
word = raw_input("Enter string: ")
for i in word:
     if(i not in punctuation):
                  newstring += i
print ("The string without punctuation is", newstring)
# SECOND METHOD
word = raw_input("Enter string: ")
punctuation = '!?,.:;"\')(_-'
newstring = word.translate(None, punctuation)
print ("The string without punctuation is",newstring)
# Output for both methods
Enter string: hello! welcome -to_python(programming.language)??,
The string without punctuation is: hello welcome topythonprogramminglanguage

Antwoord 24

Ik was op zoek naar een heel eenvoudige oplossing. dit is wat ik heb:

import re 
s = "string. With. Punctuation?" 
s = re.sub(r'[\W\s]', ' ', s)
print(s)
'string  With  Punctuation '

Antwoord 25

Rekening houdend met unicode. Code gecontroleerd in python3.

from unicodedata import category
text = 'hi, how are you?'
text_without_punc = ''.join(ch for ch in text if not category(ch).startswith('P'))

Antwoord 26

U kunt dit ook doen:

import string
' '.join(word.strip(string.punctuation) for word in 'text'.split())

Antwoord 27

Verwijder stopwoorden uit het tekstbestand met Python

print('====THIS IS HOW TO REMOVE STOP WORS====')
with open('one.txt','r')as myFile:
    str1=myFile.read()
    stop_words ="not", "is", "it", "By","between","This","By","A","when","And","up","Then","was","by","It","If","can","an","he","This","or","And","a","i","it","am","at","on","in","of","to","is","so","too","my","the","and","but","are","very","here","even","from","them","then","than","this","that","though","be","But","these"
    myList=[]
    myList.extend(str1.split(" "))
    for i in myList:
        if i not in stop_words:
            print ("____________")
            print(i,end='\n')

Antwoord 28

Ik gebruik graag een functie als deze:

def scrub(abc):
    while abc[-1] is in list(string.punctuation):
        abc=abc[:-1]
    while abc[0] is in list(string.punctuation):
        abc=abc[1:]
    return abc

LEAVE A REPLY

Please enter your comment!
Please enter your name here

2 + 5 =

Other episodes