适用于多个点和单个点的Python正则表达式

时间:2019-04-27 16:58:31

标签: python regex

我目前正在尝试清除1克文件。其中一些词如下:

  1. word-基本单词,经典情况
  2. word.-基本单词,但带有点
  3. w.s.f.w.-(单词代表单词)-正确的首字母缩写词
  4. w.s.f.w-首字母缩写词不正确(缺少最后一个点)

我当前的实现考虑了两个不同的RegExes,因为我没有成功将它们组合成一个。第一个RegEx识别基本单词:

find_word_pattern = re.compile(r'[A-Za-z]', flags=re.UNICODE)

第二个用于识别缩写词:

find_acronym_pattern = re.compile(r'([A-Za-z]+(?:\.))', flags=re.UNICODE)

假设我有一个input_word作为一个字符序列。输出是通过以下方式获得的:

"".join(re.findall(pattern, input_word))

然后我根据长度选择要使用的输出:输出越长越好。我的策略在没有案例的情况下运作良好。 1,两个模式返回相同的长度。

案例号2是有问题的,因为我的方法会产生word.(带点),但是我需要它返回word(不带点)。目前,决定使用find_acronym_pattern这种情况以产生更长的序列。

案号3符合预期。

案号4:find_acronym_pattern遗漏了最后一个字符,这意味着它会生成w.s.f.,而find_word_pattern会生成wsfw

我正在寻找一个RegEx(最好是一个,而不是当前使用的两个):

  1. 给定word返回word

  2. 给定word.返回word

  3. 给定w.s.f.w.返回w.s.f.w.

  4. 给定w.s.f.w返回w.s.f.w.

  5. 给定m.in返回m.in.

2 个答案:

答案 0 :(得分:2)

正则表达式永远不会返回不存在的内容,因此您可以忘记需求5。您可以做的就是始终删除最后一个句点,如果结果包含嵌入的句点,则将其添加回去。这将为您提供所需的结果,而且非常简单:

found = re.findall(r"\w+(?:\.\w+)*", input_word)[0]
if "." in found:
    found += "."

如您所见,我匹配一个单词以及任意数量的“ .part”后缀。像您的版本一样,它不仅匹配单个字母的首字母缩写,而且匹配更长的缩写,例如Ph.D.,Prof.Dr。博士或其他。

答案 1 :(得分:2)

如果您想要一个正则表达式,则可以使用以下内容:

((?:[A-Za-z](\.))*[A-Za-z]+)\.?

并替换为:

\1\2

Regex demo

Python 3示例:

import re

regex = r"((?:[A-Za-z](\.))*[A-Za-z]+)\.?"
test_str = ("word\n" "word.\n" "w.s.f.w.\n" "w.s.f.w\n" "m.in")
subst = "\\1\\2"

result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

输出:

word
word
w.s.f.w.
w.s.f.w.
m.in.

Python demo