Очистка текста с помощью Python и повтор - PullRequest
1 голос
/ 15 марта 2019

Мне нужно очистить текст, как показано в коде ниже:

import re
def clean_text(text):
    text = text.lower()
    #foction de replacement
    text = re.sub(r"i'm","i am",text)
    text = re.sub(r"she's","she is",text)
    text = re.sub(r"can't","cannot",text)
    text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)
    return text

clean_questions= []
for question in questions: 
    clean_questions.append(clean_text(question))

и этот код должен дать мне список questions чистый, но я получил чистый questions пустой. Я снова открыл шпион, и список заполнился, но без очистки, а затем снова открыл его, и я получил его пустым .. ошибка консоли говорит:

In [10] :clean_questions= [] 
   ...: for question in questions: 
   ...: clean_questions.append(clean_text(question))
Traceback (most recent call last):

  File "<ipython-input-6-d1c7ac95a43f>", line 3, in <module>
    clean_questions.append(clean_text(question))

  File "<ipython-input-5-8f5da8f003ac>", line 16, in clean_text
    text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)

  File "C:\Users\hp\Anaconda3\lib\re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)

  File "C:\Users\hp\Anaconda3\lib\re.py", line 286, in _compile
   p = sre_compile.compile(pattern, flags)

  File "C:\Users\hp\Anaconda3\lib\sre_compile.py", line 764, in compile
    p = sre_parse.parse(p, flags)

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 930, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 426, in _parse_sub
    not nested and not items))

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 580, in _parse
    raise source.error(msg, len(this) + 1 + len(that))

error: bad character range }-=

Я использую Python 3.6, в частности, сборку Anaconda Anaconda3-2018.12-Windows-x86_64.

Ответы [ 2 ]

4 голосов
/ 15 марта 2019

Ваш класс персонажа (как показано в трассировке) недействителен;} следует после = по порядковому значению (} равно 125, = равно 61), а - между ними означает, что он пытается сопоставить любой символ от порядкового номера } до = и между.Поскольку диапазоны символов должны переходить от низкого порядкового номера к верхнему порядковому, 125-> 61 бессмысленна, поэтому ошибка.

В некотором смысле вам повезло;если бы символы вокруг - были поменяны местами, например, =-}, вы бы молча удалили все символы с порядкового номера от 61 до 125 включительно, который включал бы, наряду с кучей знаков препинания, все стандартные буквы ASCII, обастрочные и прописные буквы.

Это можно исправить, просто удалив второй - в своем классе персонажей (вы уже включили его в начало класса, где его не нужно экранировать), изменив

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

до

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

но я собираюсь предложить отбросить здесь регулярные выражения;риск ошибок с большим количеством буквенных знаков препинания высок, и есть другие методы, которые вообще не включают регулярные выражения, которые должны работать просто отлично и не заставлять вас беспокоиться, если вы избежали всех важных вещей (альтернатива - избыточный выход,что делает регулярное выражение нечитаемым и подверженным ошибкам).

Вместо этого замените эту строку на простым str.translate вызовом .Прежде всего, вне функции, создайте таблицу перевода вещей, которые нужно удалить :

# The redundant - is harmless here since the result is a dict which dedupes anyway
killpunctuation = str.maketrans('', '', r"-()\"#/@;:<>{}-=~|.?,")

, затем замените строку:

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

на:

text = text.translate(killpunctuation)

Он должен работать по крайней мере так же быстро, как и регулярное выражение (скорее всего, быстрее), и он гораздо менее подвержен ошибкам, поскольку ни один символ не имеет специального значения (таблицы перевода - это просто отображения из ординалов Unicode в None,означает удаление, другой порядковый номер, означающий замену одного символа, или строку, означающую замену char -> multichar; у них нет понятия специальных переходов).Если целью является уничтожение всех знаков препинания ASCII, вам, вероятно, лучше использовать константу модуля string для определения таблицы перевода (что также делает код более самодокументируемым, поэтому люди не задаются вопросом, удаляете ли вы все илипросто некоторая пунктуация, и была ли она преднамеренной):

import string
killpunctuation = str.maketrans('', '', string.punctuation)

Как это бывает, ваша существующая строка не удаляет все знаки пунктуации (она пропускает, среди прочего, ^, !, $ и т. д.), поэтому это изменение может быть неверным, но если оно правильное, обязательно внесите его.Если это должна быть часть знаков препинания, вы определенно хотите добавить комментарий о том, как была выбрана эта пунктуация, поэтому сопровождающие не задаются вопросом, допустили ли вы ошибку.

0 голосов
/ 15 марта 2019

Вам необходимо правильно экранировать специальные символы и заключить в квадратные скобки

re.sub(r'[-\(\)\"#\/@;:<>\{\}\-=~|\.\?]', '', some_text)

Более общее регулярное выражение для специальных символов (т. Е. Не буквы или цифры) равно

[^a-zA-Z0-9]
...