在Java字符串中计算句子数量

3

你好,我想要计算一个字符串中句子的数量,目前我正在使用以下方法:

int count = str.split("[!?.:]+").length;

但是我的字符串中包括名称和单词之间的".",例如:

“他的名字是沃尔顿D.C.,他去年刚完成了他的B.Tech。”

现在以上述行作为示例,计数将返回4个句子,但实际上只有一个。

那么如何处理这些情况?


1
这就是我在思考如何区分的想法。 - Sahil Shokeen
JAVA 8 可以确定句子边界。 - gtgaxiola
我在使用Java进行Android开发,是否有一个库可以使用? - Sahil Shokeen
问题是我正在使用Java进行Android开发,而Android开发不支持Java 8。 - Sahil Shokeen
2
只需使用OpenNLP,这可能是最好的解决方案。 - m4gic
显示剩余8条评论
4个回答

3
你可以使用 BreakIterator,并检测不同种类的 文本边界
在您的情况下,是句子:
private static void markBoundaries(String target, BreakIterator iterator) {
    StringBuffer markers = new StringBuffer();
    markers.setLength(target.length() + 1);
    for (int k = 0; k < markers.length(); k++) {
        markers.setCharAt(k, ' ');
    }
    int count = 0;
    iterator.setText(target);
    int boundary = iterator.first();
    while (boundary != BreakIterator.DONE) {
        markers.setCharAt(boundary, '^');
        ++count;
        boundary = iterator.next();
    }
    System.out.println(target);
    System.out.println(markers);
    System.out.println("Number of Boundaries: " + count);
    System.out.println("Number of Sentences: " + (count-1));
}

public static void main(String[] args) {
    Locale currentLocale = new Locale("en", "US");
    BreakIterator sentenceIterator
            = BreakIterator.getSentenceInstance(currentLocale);
    String someText = "He name is Walton D.C. and he just completed his B.Tech last year.";
    markBoundaries(someText, sentenceIterator);
    someText = "This order was placed for QT3000! MK?";
    markBoundaries(someText, sentenceIterator);

}

输出结果将为:
He name is Walton D.C. and he just completed his B.Tech last year.
^                                                                 ^
Number of Boundaries: 2
Number of Sentences: 1
This order was placed for QT3000! MK?
^                                 ^  ^
Number of Boundaries: 3
Number of Sentences: 2

1
解决方法可以是,在遇到句点时,检查是否有一个空格和一个大写字母在它后面。 "[句点][空格][大写字母]" 这将确保该句子的正确性。
更新相应的代码:
public static void main( String args[] ) {
      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! MK? \n Thats amazing. \n But I am not sure.";
  String pattern = "([.!?])([\\s\\n])([A-Z]*)";

  // Create a Pattern object
  Pattern r = Pattern.compile(pattern);

  // Now create matcher object.
  Matcher m = r.matcher(line);
  int count=0;
  while (m.find( )) {
      count++;
  }
  count++; //for the last line, which will not get included here.
  System.out.println("COUNT=="+count);
}

@Simion,“B.Tech”不会被识别为句子分隔符(这就是Yashi的意思),但如果我正确理解了OP,它也可能是“B. Tech”,这将是一个误报。 - Thomas
只留下例子,我的重点在于逻辑。这个逻辑适用于所有测试用例。 - Yashi Srivastava
它将如何显示句子的数量? - Sahil Shokeen
@SahilShokeen,您认为这个答案解决了您的问题吗? - Yashi Srivastava
我猜你可以使用一个[DELIMITERS][NEXT LINE]的条件来解决这个问题。我会为此编辑我的代码。 - Yashi Srivastava
显示剩余6条评论

1
简单的方法 ``` public class CountLines { ```
public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s="Find the number Sentence";
    int count=0;
    for (int i = 0; i < s.length(); i++) {
        if(s.charAt(i)==' ') {
            count++;
        }
    }
    count=count+1;
    System.out.println(count);
}

}


0

一个解决方案是,如果在点之前有一个或多个大写字母,则可以跳过该点。在这种情况下,名称(如果它们是大写的)也是如此。实施此操作后,您将只有一个句子。

另一个解决方案:改进此处的一个答案可能是:[小写]([点]或[?]或[!])[空格][大写]

但正如我所说,如果没有确切的规则,这几乎是不可能的。


但并不是必须在“.”之前有大写字母,例如“b.tech”或“etc.”。 - Sahil Shokeen
我写在括号里:你应该定义一些限制,一些规则——所有用于名称的字母都必须大写(或类似这样)。否则,即使是人类也无法将一句话与另一句话分开。 - Simion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接