(Хорошо, вы разъяснили большую часть того, что вы хотите. Позвольте мне повторить, а затем уточнить пункты, которые я перечислил ниже как оставшиеся неясными... Также возьмите начальный код, который я вам покажу, адаптируйте его, опубликуйте нам результат.)
Вы хотите искать, построчно, без учета регистра, самые длинные непрерывные совпадения для каждого из пары шаблонов сопоставления. Все паттерны кажутся непересекающимися (невозможно получить совпадение как по паттерну X, так и по паттерну Y, поскольку они используют разные фразы, например, не могут сопоставляться как «лобная доля», так и «префронтальная кора»).
Ваши шаблоны представлены в виде последовательности пар ('dom','rang'), => давайте просто будем ссылаться на них по индексу [0] и [1, вы можете использовать string.split( '\t'). Важно, чтобы совпадающая строка должна совпадать с обоими шаблонами dom и rang (полностью или частично ). Порядок не зависит, поэтому мы можем сопоставить rang, затем dom или наоборот => использовать 2 отдельных регулярных выражения в строке и проверить соответствие d и r.
Шаблоны имеют необязательные части в скобках =>, поэтому просто напишите/преобразуйте их в синтаксис регулярных выражений, уже используя синтаксис (optionaltext)?, например: re.compile('Frontallobes of (leftside)? the brain', re.IGNORECASE)
Возвращаемое значение должно быть строковым буфером с самой длинной на данный момент подстрокой.
Теперь здесь нужно прояснить несколько вещей - пожалуйста, отредактируйте свой вопрос, чтобы объяснить следующее:
- Если вы найдете полное совпадение с какой-либо парой шаблонов, верните ее.
- Если вы не можете найти полных совпадений, выполните поиск частичных совпадений обоих шаблонов. Где «частичное совпадение» означает «наибольшее количество слов» или «наибольшая доля (%) слов» из шаблона? Предположительно, мы исключаем ложные совпадения с такими словами, как «the», и в этом случае мы ничего не теряем, просто опуская «the» из ваших шаблонов поиска, тогда это гарантирует, что все частичные совпадения с любым шаблоном являются значимыми.
- Мы оцениваем частичные совпадения (каким-то образом), например «содержит большинство слов из шаблона X» или «содержит наибольший % слов из шаблона X». Мы должны сделать это для всех шаблонов, а затем вернуть шаблон с наивысшим баллом. Вам нужно немного подумать об этом, лучше ли сопоставлять 2 слова шаблона из 5 слов (40%), например. 'мечты о' или 1 из 2 (50%), например. 'префронтальная, НО НЕ корковая'? Как мы разрываем связи и т.д.? Что произойдет, если мы сопоставим «сон», но ничего больше?
Каждый из вышеперечисленных вопросов повлияет на решение, поэтому вам нужно ответить на них для нас. Нет смысла писать страницы кода для решения самого общего случая, когда вам нужно только что-то простое. Обычно это называется «НЛП» (обработка естественного языка). Вы можете в конечном итоге использовать библиотеку НЛП.
Общая структура кода пока звучит так:
import re
# normally, read your input directly from file, but this allows us to test:
input = """The pons also contains the sleep paralysis center of the brain as well as generating the dreams of REM sleep.
The optic tract is a part of the visual system in the brain.
The inferior frontal gyrus is a gyrus of the frontal lobe of the human brain.
The prefrontal cortex (PFC) is the anterior part of the frontallobes of the brain, lying in front of the motor and premotor areas.
There are three possible ways to define the prefrontal cortex as the granular frontal cortex as that part of the frontal cortex whose electrical stimulation does not evoke movements.
This allowed the establishment of homologies despite the lack of a granular frontal cortex in nonprimates.
Modern tracing studies have shown that projections of the mediodorsal nucleus of the thalamus are not restricted to the granular frontal cortex in primates.
""".split('\n')
patterns = [
('(dreams of REM (Geo)? sleep)', '(sleep paralysis)'),
('(frontal lobe)', '(inferior frontal gyrus)'),
('(prefrontal cortex)', '(frontallobes of (leftside )?(the )?brain)'),
('(modern tract)', '(probably mediodorsal nucleus)') ]
# Compile the patterns as regexes
patterns = [ (re.compile(dstr),re.compile(rstr)) for (dstr,rstr) in patterns ]
def longest(t):
"""Get the longest from a tuple of strings."""
l = list(t) # tuples can't be sorted (immutable), so convert to list...
l.sort(key=len,reverse=True)
return l[0]
def custommatch(line):
for (d,r) in patterns:
# If got full match to both (d,r), return it immediately...
(dm,rm) = (d.findall(line), r.findall(line))
# Slight design problem: we get tuples like: [('frontallobes of the brain', '', 'the ')]
#... so return the longest match strings for each of dm,rm
if dm and rm: # must match both dom & rang
return [longest(dm), longest(rm)]
# else score any partial matches to (d,r) - how exactly?
# TBD...
else:
# We got here because we only have partial matches (or none)
# TBD: return the 'highest-scoring' partial match
return ('TBD... partial match')
for line in input:
print custommatch(line)
и работа с 7 строками ввода, которые вы указали в настоящее время, дает:
TBD... partial match
TBD... partial match
['frontal lobe', 'inferior frontal gyrus']
['prefrontal cortex', ('frontallobes of the brain', '', 'the ')]
TBD... partial match
TBD... partial match
TBD... partial match
TBD... partial match
person
smci
schedule
04.07.2011