【问题标题】:Split multiple joined words with upper and lower case用大写和小写拆分多个连接词
【发布时间】:2016-04-13 17:31:22
【问题描述】:

我发现了一些与此主题相关的问题。但是,我还没有找到一个解决方案,它带来了一个具体的想法,比如如何使用正则表达式将连接的单词(西班牙语)拆分为大写和小写。

我正在使用 PyPDF2 从多个 pdf 中提取文本。信息始终保持相同的顺序。

运行 PyPDF2 代码后,我得到如下项目:

'MASCULINOFecha de NacimientoLugar de Nacimiento'
'CASADONivel Educativo'

在这两种情况下,项目都是 pdf 内容中的关键词。我试图得到的输出应该是这样的(使用之前的例子):

'MASCULINO'
'Fecha de Nacimiento'
'Lugar de Nacimiento'
'CASADO'
'Nivel Educativo'

我尝试使用正则表达式模块来拆分特定模式。到目前为止,这是我的代码:

pdfFile = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFile)
for page in range(0, pdfReader.getNumPages()):
    text = pdfReader.getPage(page).extractText()
    for line in text.split(':'):
        pattern = re.compile(r'([A-Z][a-z]+(?=\s[A-Z])(?:\s[A-Z][a-z]+)+)')
        result = re.findall(pattern, line)
        print result

它拆分了一些项目,但不是全部。

有没有更好的正则表达式模式来拆分这些单词?

任何解决问题的建议都值得赞赏。谢谢

【问题讨论】:

  • 输入的原始格式是什么?
  • @noob 我编辑了这个问题。最后,我编写了我正在使用的代码。
  • 编辑:\B(?=[A-Z][a-z]) 上的拆分怎么样。它在一个大写字母后跟一个前面没有空格的小写字母之前拆分。
  • @ClasG:足够接近。但是您也必须将a-z 添加到积极的后视镜中。
  • 已更改 - 再试一次

标签: python regex python-2.7 pdf text-mining


【解决方案1】:

尝试使用(?<=[A-Za-z])(?=[A-Z][a-z]) 并替换为\n 或拆分。

这将检测大写或小写与大写或小写之间的zero-width。这似乎是这里的逻辑分隔符。

输入

MASCULINO|Fecha de Nacimiento|Lugar de Nacimiento
CASADO|Nivel Educativo

| 表示匹配的零宽度。

输出

MASCULINO
Fecha de Nacimiento
Lugar de Nacimiento
CASADO
Nivel Educativo

Regex101 Demo

正如 Wiktor 在评论中提到的那样

您不能将 re.split 与匹配正则表达式的空字符串一起使用。如果需要拆分,请使用 PyPi 正则表达式模块。

在 re.sub 中没有这种错误,它被用作一种解决方法:使用 re.sub 将未使用的字符插入到字符串中,然后用这个字符 re.split。只需选择输入中肯定不存在的一些字符(通常是控制字符,或未使用的 Unicode 范围中的字符)。

~ 替换为匹配的零宽度并在~ 上拆分将为您提供结果数组。

Python 代码:

import re
line='MASCULINOFecha de NacimientoLugar de Nacimiento CASADONivel Educativo'
result = re.sub('(?<=[A-Za-z])(?=[A-Z][a-z])', '~', line,)
result = re.split('~', result)
print result

Ideone Demo

【讨论】:

  • Regex101 演示看起来很棒。我将re.findall 更改为result = re.split(pattern, line) 但我和以前一样加入了单词。
  • @estebanpdl:在我的回答中添加了 ideone 演示。现在应该可以理解了。
  • 您不能将re.split 与匹配正则表达式的空字符串一起使用。如果需要 split,请使用 PyPi regex 模块。
  • @WiktorStribiżew:我没有意识到这一点,所以我在演示中使用了sub。我希望没关系还是有更好的解决方案?
  • @estebanpdl:在这种情况下,您可以根据需要将数字添加到前瞻或后视。如果你能解释得更多,那将会很有帮助。
【解决方案2】:

\B(?=[A-Z][a-z]) 上拆分。它会查找大写字母后跟小写字母,而小写字母前面有单词边界。

在测试用例中完成了 222 个步骤 - see it here

问候

【讨论】:

  • ▲ 巧妙地使用\B
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
  • 2022-11-13
  • 1970-01-01
  • 2010-09-16
  • 2016-08-28
  • 2015-06-19
相关资源
最近更新 更多