3

我有一个分成多行的文本,没有特定的格式。所以我决定line.strip('\n')为每一行。然后我想使用句子结束标记将文本分成句子,.考虑:

  1. .后跟\s(空格)、\S(like " ')和后跟[A-Z]将拆分的句点
  2. 不要分裂[0-9]\.[A-Za-z],喜欢1.stackoverflow real time solution

我的程序只解决了 1 - 句点 (.) 的一半,后跟 \s 和 [AZ]。下面是代码:

# -*- coding: utf-8 -*-
import re, sys

source = open(sys.argv[1], 'rb')
dest = open(sys.argv[2], 'wb')
sent = []
for line in source:
    line1 = line.strip('\n')
    k = re.sub(r'\.\s+([A-Z“])'.decode('utf8'), '.\n\g<1>', line1)
    sent.append(k)

for line in sent:
    dest.write(''.join(line))

请!我想知道哪个是掌握正则表达式的最佳方法。这似乎令人困惑。

4

1 回答 1

4

要在字符类中包含单引号,请使用\对其进行转义。正则表达式应该是:

\.\s+[A-Z"\']

这就是你真正需要的。你只需要告诉一个正则表达式匹配什么,你不需要指定你不想匹配什么。所有不符合模式的东西都不会匹配。

此正则表达式将匹配任何句点,后跟空格,后跟大写字母或引号。由于紧跟在数字前面并紧跟在字母后面的句点不符合这些条件,因此不匹配。

正如您所说,这是假设您使用的正则表达式正在拆分一个句点,然后是空格,然后是大写字母。但是请注意,这意味着I am Sam. Sam I am.将拆分为I am Samam I am。这真的是你想要的吗?如果没有,请使用零宽度断言来排除要匹配但也要保留的部分。以下是您的选择,按照我认为您最可能想要的顺序排列。

1) 保留句号和下一句的首字母或开头引号;丢失空格:

(?<=\.)\s+(?=[A-Z"\'])

这会将上面的示例拆分为I am Sam.Sam I am.

2)保留下一句的第一个字母;失去句号和空格:

\.\s+(?=[A-Z"\'])

这将拆分为I am SamSam I am。这假定后面还有更多的句子,否则句号将与第二句保持一致,因为它后面没有空格和大写字母或引号。如果此选项是您想要的选项 -没有句点的句子,那么您可能还想匹配一个句点,然后是字符串的结尾,并带有可选的中间空格,以便最后一个句点和任何尾随空格都将被删除:

\.(?:\s+(?=[A-Z"\'])|\s*$)

注意?:. 您需要非捕获括号,因为如果您在拆分中有捕获组,则该组捕获的任何内容都将作为元素添加到结果中(例如split('(+)', 'a+b+c',为您提供一个数组,a + b + c而不仅仅是a b c)。

3) 保留一切;空格与前面的句子一起使用:

(?<=\.\s+)(?=[A-Z"\'])

这会给你I am Sam.Sam I am.

关于你问题的最后一部分,我见过的正则表达式语法的最佳资源是http://www.regular-expressions.info。从这个摘要开始:http ://www.regular-expressions.info/reference.html然后转到教程页面了解更多高级细节:http ://www.regular-expressions.info/tutorial.html

于 2013-08-05T00:54:50.387 回答