第一个字符被删除(正则表达式)

时间:2012-12-27 18:36:16

标签: python regex python-3.x

我有这个正则表达式: (?<=[.!?])\s[A-Z] 我在这个文本上运行它:

The engineering plant, weapon and electronic systems, galley, and multitudinous other
equipment required to transform the new hull into an operating and habitable warship are
installed and tested. The prospective commanding officer, ship's officers, the petty
officers, and seamen who will form the crew report for training and intensive
familiarization with their new ship.

它产生:

he engineering plant, weapon and electronic systems, galley, and multitudinous other
equipment required to transform the new hull into an operating and habitable warship are
installed and tested.
he prospective commanding officer, ship's officers, the petty officers, and seamen who
will form the crew report for training and intensive familiarization with their new ship.

如您所见,它删除了句子的第一个字母。这不是因为它们是大写的(我测试过它)。

如何修复它以便它不会删除句子的第一个字母?

(我正在使用Python 3)

我使用了re.split(),然后我打印了数组,用换行符分隔每个值

2 个答案:

答案 0 :(得分:2)

您的正则表达式匹配空白字符和大写ASCII字母,但前提是它们前面有点,感叹号或问号。

当您使用它来分割文本时,大写字母成为用于分割的分隔符的一部分,因此被删除。

将正则表达式更改为

(?<=[.!?])\s(?=[A-Z])

并且这封信不会成为比赛的一部分。

但请注意两件事:

  1. 仅当新句子以ASCII字母开头时才会起作用。对于大多数英语句子,你可能没问题,但肯定不适用于其他语言。
  2. 如果您的文字包含缩写词,则可能会出现一些错误的分词:Mr. SmithDr. Jones将分为两部分。

答案 1 :(得分:1)

问题出在你的正则表达式上,奇怪的是,当你使用“非消费令牌”(即正面的后置)来标点符号((?<=[.!?]))时,你没有检测到每个句子的第一个字母([A-Z])。

因此,您在split()中使用的正则表达式将消耗每个匹配的第一个大写字母。你可能意味着不要消耗它(也就是说,只消耗它们之间的空间),在这种情况下你想要使用一个不消耗文本的正向前瞻:

(?<=[.!?])\s(?=[A-Z])

Lookaheads和lookbehinds一般是锚点,锚点不会从输入中消耗任何文本。最常用的锚点当然是^$。它们只匹配输入文本中的位置,这就是您想要的。

lookbehind将匹配前一个文本与该位置必须匹配/不匹配给定正则表达式的位置,而前瞻将匹配后续文本的位置到该位置必须匹配/不匹配给定的正则表达式。在匹配的空格之后,你想要的是一个大写字母的位置,因此使用正面的前瞻((?=<re>),其中<re>是正则表达式)匹配大写字母({ {1}} <re>}。