Получить определение для заключенной в скобки аббревиатуры на основе количества букв - PullRequest
6 голосов
/ 02 июня 2019

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

String = 'Хотя история здоровья семьи (FHH) обычно считается важным фактором риска для распространенных хронических заболеваний, она редко рассматривается практикующей медсестрой (NP).'

Желаемый результат: история здоровья семьи (FHH), практикующая медсестра (NP)

Я знаю, как извлечь скобки из строки, но после этого я застрял. Любая помощь приветствуется.

 import re

 a = 'Although family health history (FHH) is commonly accepted as an 
 important risk factor for common, chronic diseases, it is rarely considered 
 by a nurse practitioner (NP).'

 x2 = re.findall('(\(.*?\))', a)

 for x in x2:
    length = len(x)
    print(x, length) 

Ответы [ 5 ]

5 голосов
/ 02 июня 2019

Используйте регулярное выражение, чтобы найти позицию начала матча. Затем используйте индексацию строки Python, чтобы получить подстроку, ведущую к началу совпадения. Разделите подстроку по словам и получите последние n слов. Где n - длина сокращения.

import re
s = 'Although family health history (FHH) is commonly accepted as an important risk factor for common, chronic diseases, it is rarely considered by a nurse practitioner (NP).'


for match in re.finditer(r"\((.*?)\)", s):
    start_index = match.start()
    abbr = match.group(1)
    size = len(abbr)
    words = s[:start_index].split()[-size:]
    definition = " ".join(words)

    print(abbr, definition)

Это печатает:

FHH family health history
NP nurse practitioner
2 голосов
/ 02 июня 2019

Идея использования рекурсивного шаблона с модулем регулярных выражений PyPI .

\b[A-Za-z]+\s+(?R)?\(?[A-Z](?=[A-Z]*\))\)?

См. Эту демонстрацию pcre на regex101

  1. Не проверяет, соответствует ли буква первого слова букве в позиции всокращение.
  2. Не проверяет наличие открывающей скобки перед сокращением.Чтобы проверить, добавьте вид сзади переменной длины.Измените [A-Z](?=[A-Z]*\)) на (?<=\([A-Z]*)[A-Z](?=[A-Z]*\)).
1 голос
/ 02 июня 2019

это решит вашу проблему?

a = 'Although family health history (FHH) is commonly accepted as an important risk factor for common, chronic diseases, it is rarely considered by a nurse practitioner (NP).'
splitstr=a.replace('.','').split(' ')
output=''
for i,word in enumerate(splitstr):
    if '(' in word:
        w=word.replace('(','').replace(')','').replace('.','')
        for n in range(len(w)+1):
            output=splitstr[i-n]+' '+output

print(output)

на самом деле, Китинге побил меня этим

0 голосов
/ 02 июня 2019

Это решение не очень умное, оно упрощает поиск сокращений и затем создает шаблон для извлечения слов перед каждым:

import re

string = "Although family health history (FHH) is commonly accepted as an important risk factor for common, chronic diseases, it is rarely considered by a nurse practitioner (NP)."

definitions = []

for acronym in re.findall(r'\(([A-Z]+?)\)', string):
    length = len(acronym)

    match = re.search(r'(?:\w+\W+){' + str(length) + r'}\(' + acronym + r'\)', string)

    definitions.append(match.group(0))

print(", ".join(definitions))

OUTPUT

> python3 test.py
family health history (FHH), nurse practitioner (NP)
>
0 голосов
/ 02 июня 2019

Использование re с list-comprehension

x_lst = [ str(len(i[1:-1])) for i in re.findall('(\(.*?\))', a) ]

[re.search( r'(\S+\s+){' + i + '}\(.{' + i + '}\)', a).group(0) for i in x_lst]
#['family health history (FHH)', 'nurse practitioner (NP)']
...