Python: вопрос о разборе читаемого человеком текста - PullRequest
2 голосов
/ 20 июля 2009

Я разбираю читаемый человеком научный текст, который в основном относится к области химии. Меня интересует разбивка текста на список слов, научных терминов (подробнее об этом ниже) и знаков препинания.

Так, например, я ожидаю текст "Привет, мир". разбить на 4 токена: 1) «привет»; 2) запятая; 3) «мир» и 4) период. Обратите внимание, что пробелы не требуют специализированных токенов.

Проблема связана с «научными терминами»: это названия химических формул, таких как «1-метил-4-фенилпиридиний». Любой, кто когда-либо изучал химию, знает, что эти формулы могут быть довольно длинными и могут содержать числа, тире и запятые, а иногда даже круглые скобки, но я думаю, что можно с уверенностью предположить, что эти милые выражения не могут содержать пробелов. Кроме того, я считаю, что эти выражения должны начинаться с цифры. Мне бы хотелось, чтобы каждое такое выражение выглядело как единое целое.

Сегодня я использую ручной анализ, чтобы найти «куски» текста, которые начинаются с цифры и заканчиваются либо пробелом, разрывом строки или знаком пунктуации, за которым следует либо пробел, либо разрыв строки.

Мне было интересно, есть ли разумное решение (регулярное выражение или другое), которое я могу использовать для токенизации текста в соответствии с приведенными выше спецификациями. Я работаю в Python, но это может быть не зависит от языка.

Пример ввода (очевидно, игнорируя содержимое ...):

«Здравствуйте. 1-метил-4-фенилпиридиний - это очень плохо. Однако 1-метил-4-фенил-1,2,3,6-тетрагидропиридин хуже».

Пример вывода (каждый токен в отдельной строке):

Hello
.
1-methyl-4-phenylpyridinium
is
ultra
-
bad
.
However
,
1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine
is
worse
.

Ответы [ 3 ]

2 голосов
/ 20 июля 2009

Это решит ваш текущий пример. Его можно настроить для большего набора данных.

import re
splitterForIndexing = re.compile(r"(?:[a-zA-Z0-9\-,]+[a-zA-Z0-9\-])|(?:[,.])")
source = "Hello. 1-methyl-4-phenylpyridinium is ultra-bad. However, 1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine is worse."
print "\n".join( splitterForIndexing.findall(source))

Результат:

"""
Hello
.
1-methyl-4-phenylpyridinium
is
ultra-bad
.
However
,
1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine
is
worse
.
"""

Извините, не видел ультра-плохо. Если необходимо, чтобы эти слова были разделены ..

import re
splitterForIndexing = re.compile(r"(?:[a-zA-Z]+)|(?:[a-zA-Z0-9][a-zA-Z0-9\-(),]+[a-zA-Z0-9\-()])|(?:[,.-])")
source = "Hello. 1-methyl-4-phenylpyridinium is ultra-bad. However, 1-methyl-4-phenyl-1,(2,3),6-tetrahydropyridine is worse."
print "\n".join( splitterForIndexing.findall(source))

Дает:

"""
Hello
.
1-methyl-4-phenylpyridinium
is
ultra
-
bad
.
However
,
1-methyl-4-phenyl-1,(2,3),6-tetrahydropyridine
is
worse
.
"""
0 голосов
/ 21 июля 2009

Я согласен с Себастьяном Мегенсом в том, что решение регулярных выражений может быть возможным, но, вероятно, не очень читабельным или обслуживаемым, особенно если вы не очень хорошо разбираетесь в регулярных выражениях. Я бы порекомендовал модуль pyparsing , если вы придерживаетесь Python (что я считаю хорошим выбором).

Дополнительная ремонтопригодность очень пригодится, если ваши потребности в анализе будут расти или изменяться. (И я уверен, что многие люди скажут «когда», а не «если»! Например, кто-то уже прокомментировал, что вам может понадобиться более сложное представление о том, что должно быть разрешено в качестве химического названия. Возможно, ваши требования уже меняется, прежде чем вы даже выбрали свой инструмент!)

0 голосов
/ 20 июля 2009

Может быть регулярное выражение, разбирающее то, что вы хотите, но я не думаю, что оно будет очень читабельным / поддерживаемым. Мой совет - использовать генератор парсеров, такой как ANTLR. Я думаю, вам придется выбросить за борт идею о том, что вы можете сделать химические описания одним токеном, слишком сложным. У ANTLR даже есть отладчик, так что вы можете понять, почему он не выполняет синтаксический анализ того, что вы считаете нужным, я не думаю, что это возможно с помощью регулярных выражений.

С уважением,

Sebastiaan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...