python разделить - Разделение строки на слова и пунктуацию




5 Answers

Это более или менее способ сделать это:

>>> import re
>>> re.findall(r"[\w']+|[.,!?;]", "Hello, I'm a string!")
['Hello', ',', "I'm", 'a', 'string', '!']

Фокус в том, чтобы не думать о том, где разделить строку, но что включить в токены.

Предостережения:

  • Подчеркивание (_) считается символом внутреннего слова. Замените \ w, если вы этого не хотите.
  • Это не будет работать с (одиночными) кавычками в строке.
  • Поместите любые дополнительные знаки препинания, которые вы хотите использовать в правой половине регулярного выражения.
  • Все, что явно не упоминается в re, тихо отбрасывается.
слово шаблоны

Я пытаюсь разбить строку на слова и пунктуацию, добавив пунктуацию в список, созданный разделом.

Например:

>>> c = "help, me"
>>> print c.split()
['help,', 'me']

Я действительно хочу, чтобы список выглядел так:

['help', ',', 'me']

Итак, я хочу, чтобы строка была разделена на пробелы с разделителем пунктуации от слов.

Сначала я попытался разобрать строку, а затем запустить split:

>>> for character in c:
...     if character in ".,;!?":
...             outputCharacter = " %s" % character
...     else:
...             outputCharacter = character
...     separatedPunctuation += outputCharacter
>>> print separatedPunctuation
help , me
>>> print separatedPunctuation.split()
['help', ',', 'me']

Это дает результат, который я хочу, но на больших файлах он очень медленный.

Есть ли способ сделать это более эффективно?




В синтаксисе регулярных выражений в стиле perl \b соответствует границе слова. Это должно пригодиться для разделения на основе регулярных выражений.

edit: Мне сообщили, что «пустые совпадения» не работают в функции split модуля re. Я оставлю это здесь в качестве информации для кого-то еще, озадаченного этой «особенностью».




Вот небольшое обновление вашей реализации. Если вы пытаетесь сделать что-нибудь более подробное, я предлагаю заглянуть в NLTK, предложенный le dorfier.

Это может быть только немного быстрее, так как вместо «=» используется символ .join (), который, как известно, быстрее .

import string

d = "Hello, I'm a string!"

result = []
word = ''

for char in d:
    if char not in string.whitespace:
        if char not in string.ascii_letters + "'":
            if word:
                    result.append(word)
            result.append(char)
            word = ''
        else:
            word = ''.join([word,char])

    else:
        if word:
            result.append(word)
            word = ''
print result
['Hello', ',', "I'm", 'a', 'string', '!']



Я придумал способ tokenize всех слов и \W+ шаблонов с использованием \b который не требует жесткого кодирования:

>>> import re
>>> sentence = 'Hello, world!'
>>> tokens = [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', sentence)]
['Hello', ',', 'world', '!']

Здесь .*?\S.*? это шаблон, сопоставляющий все, что не является пространством, и $ добавляется для соответствия последнему токену в строке, если это символ пунктуации.

Обратите внимание на следующее: это будет группировать знаки препинания, состоящие из более чем одного символа:

>>> print [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', '"Oh no", she said')]
['Oh', 'no', '",', 'she', 'said']

Конечно, вы можете найти и разделить такие группы:

>>> for token in [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', '"You can", she said')]:
...     print re.findall(r'(?:\w+|\W)', token)

['You']
['can']
['"', ',']
['she']
['said']



Вы пытались использовать регулярное выражение?

http://docs.python.org/library/re.html#re-syntax

Кстати. Зачем вам нужно «,» на втором? Вы узнаете, что после того, как будет записан каждый текст, т.е.

[0]

""

[1]

""

Поэтому, если вы хотите добавить «,», вы можете просто сделать это после каждой итерации при использовании массива.




Related

python string split