регулярное выражение для ловли сокращений - PullRequest
0 голосов
/ 12 марта 2020

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

x = 'Confirmatory factor analysis (CFA)  is a special case of what is known as structural equation modelling (SEM).'

re.findall(r'\b([A-Za-z][a-z]+(?:\s[A-Za-z][a-z]+)+)\s+\(([A-Z][A-Z]*[A-Z]\b\.?)',x)

out:

[('Confirmatory factor analysis', 'CFA'),
 ('special case of what is known as structural equation modeling', 'SEM')]

Ответы [ 3 ]

1 голос
/ 12 марта 2020
  1. Существует только один способ узнать, сколько слов до (CFA) составляют так называемую полную форму: посмотрите количество альф в группе 2 (назначьте l), разбейте группа 1 на пустом месте, возьмите последние l слова, основанные на длине группы 2, и затем воссоединитесь.

  2. Ваше регулярное выражение будет принимать (CFA.), но не (C. FA) поэтому небольшое изменение в вашем регулярном выражении для того, чтобы разрешить дополнительный период после каждой альфы, и кажется, что вы пытаетесь сказать, что сокращение должно состоять из двух или более буквенных символов - есть более простой способ express что.

Перейдите в группу 2 в регулярном выражении:

(                    # start of group 2
  (?:                # start of non-capturing group
     [A-Z]           # an alpha character
     \.?             # optionally followed by a period
  )                  # end of non-capturing group
  {2,}               # the non-capturing group is repeated 2 or more times
)                    # end of group 2

Код:

#!/usr/bin/env python3

import re

x = 'Confirmatory factor analysis (CFA)  is a special case of what is known as structural equation modelling (S.E.M.).'
results = []
split_regex = re.compile(r'\s+')
for m in re.finditer(r'\b([A-Za-z][a-z]*(?:\s[A-Za-z][a-z]*)+)\s+\(((?:[A-Z]\.?){2,})\)', x):
    abbreviation = m[2]
    l = sum(c.isalpha() for c in abbreviation)
    full_form = ' '.join(split_regex.split(m[1])[-l:])
    results.append([full_form, abbreviation])
print(results)

Печать

[['Confirmatory factor analysis', 'CFA'], ['structural equation modelling', 'S.E.M.']]

Python Демо

0 голосов
/ 12 марта 2020

Я использовал регулярное выражение и разделил строку на (или). Затем создайте список кортежей в последовательном индексе.

import re
x = 'Confirmatory factor analysis (CFA)  is a special case of what is known as structural equation modelling (SEM).'
lst = re.split('\(|\)', x)
lst = [(lst[i*2].strip(), lst[i*2+1].strip()) for i in range(0, len(lst)//2)]
final = []
for i in range(len(lst)):
    abbr = lst[i][1]
    text = ' '.join(lst[i][0].split(' ')[-len(abbr):])
    final.append((abbr, text)) 
final

Результат:

 [('CFA', 'Confirmatory factor analysis'),
 ('SEM', 'structural equation modelling')]
0 голосов
/ 12 марта 2020

попробуйте это - это работает, ища заглавную строку, заключенную в скобки. Затем мы проверяем, что предыдущие слова соответствуют аббревиатуре.


import re

string = 'Confirmatory factor analysis (CFA)  is a special case of what is known as structural equation modelling (SEM).'

abbrvs  = re.findall("\(([A-Z][A-Z]+)\)", string) #find potential abbrvs

words = re.split("\s|\.|,", string) 

validated_abbrvs = []
for abbrv in abbrvs:
    end = words.index(f"({abbrv})")
    start = end - len(abbrv) 
    full_name = words[start:end] #locate preceeding words
    if "".join([w[0].upper() for w in full_name]) == abbrv: #validate it matches abbrv
        validated_abbrvs.append((abbrv, " ".join(full_name)))

print(validated_abbrvs)

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