Как использовать re.findall, чтобы найти слова, которые НЕ из всех заглавных букв? - PullRequest
0 голосов
/ 15 ноября 2018

Например, у меня есть s="I REALLY don't want to talk about it, not at all!"

Я хочу re.findall(reg, s), чтобы вернуться "I" "don't" "want" "to" "talk" "about" "it" "," "not" "at" "all" "!"

Пока я получил reg=r'[^\w\s]+|\w+|\n', который не может отфильтровать слово "REALLY"

спасибо

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Эта цитата Брайана Кернигана особенно верна для регулярных выражений.

Все знают, что отладка в два раза сложнее, чем писать программу в первую очередь.Так что если вы настолько умны, насколько это возможно, когда вы пишете, как вы будете отлаживать его?

Так что, если что-то трудно сделать в одном регулярном выражении, вы можете разделитьэто в два этапа.Сначала найдите все слова, а затем отфильтруйте все заглавные слова.Легче понять и легче тестировать.

>>> import re
>>> s="I REALLY don't want to talk about it, not at all!"
>>> words = re.findall(r"[\w']+", s)
>>> words = [w for w in words if w.upper() != w]
>>> print(words)
["don't", 'want', 'to', 'talk', 'about', 'it', 'not', 'at', 'all']
0 голосов
/ 15 ноября 2018

Шаблон \w+ соответствует 1 или более любым символам слова, включая слова в ALLCAPS.

Обратите внимание, что I, местоимение, также является ALLCAPS. Таким образом, предполагая, что вы хотите пропустить все слова ALLCAPS из 2 или более букв, вы можете рассмотреть возможность исправления текущего шаблона как

r'[^\w\s]+|\b(?![A-Z]{2,}\b)\w+|\n'

См. Демоверсию regex

Шаблон \b(?![A-Z]{2,}\b)\w+ соответствует

  • \b - граница слова
  • (?![A-Z]{2,}\b) - отрицательный прогноз, который не соответствует совпадению, если непосредственно справа от текущего местоположения имеются 2 или более прописных буквы ASCII, за которыми следует граница слова
  • \w+ - 1 или более символов слова (если вы хотите сопоставлять только буквы, замените на [^\W\d_]+).

Чтобы поддерживать все заглавные буквы Unicode, вы можете использовать регулярное выражение PyPi с шаблоном r'[^\w\s]+|\b(?!\p{Lu}{2,}\b)\w+|\n' или создать класс, используя pLu = '[{}]'.format("".join([chr(i) for i in range(sys.maxunicode) if chr(i).isupper()])) (Python 3) или pLu = u'[{}]'.format(u"".join([unichr(i) for i in xrange(sys.maxunicode) if unichr(i).isupper()])) (Python 2). См. регулярное выражение Python для заглавных слов в юникоде . Примечание. Я бы рекомендовал придерживаться последних версий Python или последних модулей регулярных выражений PyPi.

...