Как разбить строку, используя длину слова в качестве токена - PullRequest
3 голосов
/ 30 марта 2019

Я готовлю строки, содержащие заголовки документов, для использования в качестве поисковых терминов на веб-сайте патента США с использованием Python 3.

1) Полезно хранить длинные фразы, но

2) поиск не дает результатов, если он содержит много слов длиной не более 3 символов, поэтому мне нужно их исключить.

Я пытался использовать регулярное выражение "\ b \ w [1: 3} \ b *", чтобы разделить одно-трехбуквенные слова с пробелом или без него, но безуспешно. Но тогда я не эксперт по регулярным выражениям.

for pubtitle in df_tpdownloads['PublicationTitleSplit']:
    pubtitle = pubtitle.lower() # make lower case
    pubtitle = re.split("[?:.,;\"\'\-()]+", pubtitle) # tokenize and remove punctuation
    #print(pubtitle)

    for subArray in pubtitle:
        print(subArray)
        subArray = subArray.strip()
        subArray = re.split("(\b\w{1:3}\b) *", subArray) # split on words that are < 4 letters
        print(subArray)

Приведенный выше код проходит серию панд и очищает знаки препинания, но не разбивает по длине слова.

Я ожидаю увидеть что-то похожее на примеры ниже.

Примеры:

Итак,

" and training requirements for selected salt applications"```

становится

['training requirements', 'selected salt applications'].

И

"december 31"

становится

['december'].

И

"experimental system for salt in an emergence research and applications in process heat"

становится

['experimental system', 'salt', 'emergence research', 'applications', 'process heat'].

Но разделение не охватывает мелкие слова, и я не могу сказать, является ли проблема регулярным выражением, командой re.split или обоими.

Я, вероятно, могу использовать метод грубой силы, но хотел бы элегантного решения. Любая помощь будет оценена.

1 Ответ

1 голос
/ 30 марта 2019

Вы можете использовать

list(filter(None, re.split(r'\s*\b\w{1,3}\b\s*|[^\w\s]+', pubtitle.strip().lower())))

чтобы получить желаемый результат. Смотрите regex demo .

Регулярное выражение r'\s*\b\w{1,3}\b\s*|[^\w\s]+' разбивает строку в нижнем регистре (с .lower()) без начальных и конечных пробелов (из-за .strip()) на токены, которые не имеют пунктуации (это делает [^\w\s]+) и не содержат 1-3 слова char слова (\s*\b\w{1,3}\b\s* делает это).

Детали шаблона

  • \s* - 0+ пробелов
  • \b - граница слова
  • \w{1,3} - 1, 2 или 3 слова (если вы не хотите совпадать _ используйте [^\W_]+)
  • \b - граница слова
  • \s* - 0+ пробелов
  • | - или
  • [^\w\s]+ - 1 или более символов кроме слов и пробелов.

См. Демоверсию Python :

import re

df_tpdownloads = [" and training requirements for selected salt applications",
                  "december 31",
                  "experimental system for salt in an emergence research and applications in process heat"]

#for pubtitle in df_tpdownloads['PublicationTitleSplit']:
for pubtitle in df_tpdownloads:
    result = list(filter(None, re.split(r'\s*\b\w{1,3}\b\s*|[^\w\s]+', pubtitle.strip().lower())))
    print(result)

Выход:

['training requirements', 'selected salt applications']
['december']
['experimental system', 'salt', 'emergence research', 'applications', 'process heat']
...