What is a quick way to split a unicode string into a list using spaces or punctuation as a delimiter?

 # -*- coding: utf-8 -*-
 import string
 s = u"Dobre uczynki są jak dobre poematy. Można łatwo uchwycić, ku czemu zmierzają, lecz nie zawsze da się je racjonalnie wytłumaczyć."
 exclude = set(string.punctuation)
 s = ''.join(ch for ch in s if ch not in exclude)
 s = s.split()
 print s

prints ...

 [u'Dobre', u'uczynki', u's\u0105', u'jak', u'dobre', u'poematy', u'Mo\u017cna', u'\u0142atwo', u'uchwyci\u0107', u'ku', u'czemu', u'zmierzaj\u0105', u'lecz', u'nie', u'zawsze', u'da', u'si\u0119', u'je', u'racjonalnie', u'wyt\u0142umaczy\u0107']

It seems that it is not only inelegant, but also slow.

Can you find a better solution? Maybe using regex?

+3
source share
4 answers

Use re.compile if you have to reuse the regex and use re.split .

import string
import re

s = u"Dobre uczynki są jak dobre poematy. Można łatwo uchwycić, ku czemu zmierzają, lecz nie zawsze da się je racjonalnie wytłumaczyć."
regex = re.compile(r'[%s\s]+' % re.escape(string.punctuation))
print regex.split(s)
+6
source

Use Regular Expressions !

# -*- coding: utf-8 -*-
import re
s = u"Dobre uczynki są jak dobre poematy. Można łatwo uchwycić, ku czemu zmierzają, lecz nie zawsze da się je racjonalnie wytłumaczyć."
print re.split('\W+', s, flags=re.UNICODE)

Of course, you can use a more specific regular expression, but it seems to fit the bill.

, flags python 2.7+. , '\W+(?u)' .

+1

That should do it. (I agree that I haven't tested it yet, though)

import re, string
s = 'your string ...'
re.split('\s'+''.join(string.punctuation), s)

EDIT: Do not use mine. Mahmoud Abdelkader answered above.

0
source

I would use nltk and this is why:

# coding: utf-8
from time import time
import nltk
import string
import re


def bench(n,s):
    start_1 = time()
    regex = regex = re.compile(r'[%s\s]+' % re.escape(string.punctuation))
    for i in xrange(n):
        regex.split(s)
    stop_1 = time()
    start_2 = time()
    for i in xrange(n):
        nltk.wordpunct_tokenize(s)
    stop_2=time()
    print "Regex: {} nltk:{}".format((stop_1-start_1),(stop_2-start_2))


bench(1000000, u"Dobre uczynki są jak dobre poematy. Można łatwo uchwycić, ku czemu zmierzają, lecz nie zawsze da się je racjonalnie wytłumaczyć.")

Regex: 22.7673070431 nltk: 16.1646370888

0
source

All Articles