如何将句段拆分为以句点(。)分隔的句子,除非句点是缩写的一部分?

时间:2012-01-09 20:06:14

标签: regex string parsing

考虑本文的段落

  

保护组织将这项为期20年的禁令称为对美国偶像的重要保护。采矿业和一些共和党国会议员表示,这对亚利桑那州的经济和国家的能源独立都是有害的。“尽管采矿业面临巨大压力,但总统和萨拉查部长并未退缩,”美国公共土地总监简·丹诺维茨说。皮尤环境集团。

在上文中,它很容易在句点(。)中分割句子,但在处理美国时期时会导致错误的结果。假设我有一个缩写列表,例如

String abbrev[] ={"u.s.a", "u.a.e", "u.k", "p.r.c","u.s.s.r", };
String regex= "\\.";
Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(sx);
int beginIndex=0;

// Check all occurance
int index=0;
while (matcher.find()) {
    System.out.print("Start index: " + matcher.start());
    System.out.print(" End index: " + matcher.end() + " ");

    String group=matcher.group();
    System.out.println("group: " + group);
    int dotIndex= group.indexOf(".");
    String sub= sx.substring(beginIndex, matcher.start()+dotIndex);
    beginIndex= matcher.start()+dotIndex;

    System.out.println(sub);
}            

我可以使用dotIndex周围的所有缩写进行强力匹配。有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我最好的猜测是:(?<!\.[a-zA-Z])\.(?![a-zA-Z]\.)会转换为:

(?<!\.[a-zA-Z])    # can't be preceded by a period followed by a single letter
\.
(?![a-zA-Z]\.)     # nor can it be followed by a letter and another preiod

然后你可以从那里进行替换。

Demo

如果您需要在引号内捕捉句点,这将需要更多的努力,在上述模式中

答案 1 :(得分:1)

依赖正则表达式无法解决此问题。要知道句子在任何给定时期是否结束并不简单。缩写可能是也可能不是句子的结尾。椭圆可以写成三个句点(或者,在某些情况下,四个,取决于主流风格)。句子有时会在一个标志着句子结束的句号之后出现的结束引号之后结束(再次取决于主流风格)。

您可以使用启发式方法在大多数时间获得正确答案。但它更像是统计问题,而不是正则表达式问题。