【问题标题】:regex for catching abbreviations用于捕获缩写的正则表达式
【发布时间】:2020-03-12 16:44:15
【问题描述】:

我正在尝试制作一个匹配字符串中的缩写及其完整形式的正则表达式。我有一个捕获某些情况的正则表达式,但在下面的示例中,它捕获的单词多于应有的单词。谁能帮我解决这个问题?

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)

出来:

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

【问题讨论】:

  • 它应该匹配什么?匹配缩写的预期标准是什么?
  • 我认为将首字母缩写词与其原词联系起来是没有规则的。例如,“受激辐射的光放大”和LASER。它们的长度不同。您应该决定如何将首字母缩略词与其原词联系起来。
  • 它必须捕获代表首字母缩写词的每个单词。在我的例子中,第一个是正确的,而第二个已经抓住了更多的词。它应该只匹配结构方程建模。我对正则表达式很陌生
  • 使用(?<=\()[A-Z]+(?=\)) 可以轻松捕获您的首字母缩写词,因此一旦您这样做了,您只需翻译它们。
  • SEM 可以是“S所谓结构E方程M建模的特殊情况”的首字母缩写。首字母缩略词取决于其定义。我认为问题在于如何找出原始单词。在正则表达式之前。

标签: python regex python-3.x string


【解决方案1】:
  1. 只有一种方法可以知道(CFA)之前有多少单词构成所谓的完整形式:查看第 2 组中的 alpha 数量(分配给l),将第 1 组拆分为空格,根据第2组的长度取最后一个l单词,然后重新加入。

  2. 您的正则表达式将接受 (CFA.) 但不接受 (C.F.A.),因此对您的正则表达式稍作修改是为了在每个 alpha 之后允许一个可选的句点,并且您似乎试图说缩写必须包含两个或多个字母字符 - 有一种更简单的方式来表达。

在正则表达式中更改为第 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 Demo

【讨论】:

  • 非常感谢。对于首字母缩写词不在括号中且长格式不在括号中的情况,您将如何更改正则表达式。就像字符串是“LOL 是一个首字母缩略词,意思是大声笑出来”一样。
  • 您确实应该提出另一个问题,现在您已经了解了我是如何解决这个问题的,您应该首先尝试解决新问题并展示您尝试过的方法。我相信你会得到很多人乐于提供帮助,包括我自己。顺便说一句,如果您还没有,请查看What should I do when someone answers my question?
  • 但它看起来相当困难,除非laughing out loud,即。 e. “完整形式”,保证后面没有任何其他词。
  • 我实际上刚刚更新了正则表达式,意识到它不能识别单字母单词。
【解决方案2】:

试试这个——它通过查找用括号括起来的大写字符串来工作。然后我们验证前面的单词是否匹配 abbrv。


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)

【讨论】:

  • 如果缩写是(CFA.),这是 OP 的正则表达式所允许的。您的解决方案将无法找到所有缩写词。
  • 也许我误会了。是的,他的正则表达式可能会捕捉到,但这就是意图吗?好像格式无效。
  • 永远不知道。我建议更改正则表达式以允许(C.F.A.),这似乎是合理的。但在这种情况下,您必须小心并认识到 有效 长度是 3 而不是 6,即您需要计算实际的 alpha 字符。看看我的解决方案。
  • 取决于格式。千种方式可以缩写。从技术上讲,缩写可能是 COFAAN。你需要规则。标点符号也可以忽略,因为它与搜索无关
  • 在搜索时忽略标点符号string = string.replace(".","") --如果这是一个要求
【解决方案3】:

我使用了正则表达式并用 ( 或 ) 分割字符串。 然后在顺序索引中创建一个元组列表。

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')]

【讨论】:

  • SEM不是is a special case of what is known as structural equation modelling的缩写,而是structural equation modelling的缩写。
猜你喜欢
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多