String x=" i am going to the party at 6.00 in the evening. are you coming with me?";
如果我有上面的字符串,我需要通过使用句子边界标点(如。和?)将其分解为句子
但它不应该将句子拆分为6,因为那里有一个指针。有没有办法确定java中正确的句子边界位置是什么?我已经尝试在java.util pakage中使用stringTokenizer但它总是在找到指针时打破句子。有人可以建议我一个正确的方法吗?
这是我尝试将文本标记为句子的方法。
public static ArrayList<String> sentence_segmenter(String text) {
ArrayList<String> Sentences = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(text, ".?!");
while (st.hasMoreTokens()) {
Sentences.add(st.nextToken());
}
return Sentences;
}
我也有一种方法可以将句子分成短语,但是当程序找到逗号(,)时,它也会分割文本。但我不需要拆分它,当有一个数字像60,000,中间有一个逗号。以下是我用来分割短语的方法。
public static ArrayList<String> phrasesSegmenter(String text) {
ArrayList<String> phrases = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(text, ",");
while (st.hasMoreTokens()) {
phrases.add(st.nextToken());
}
return phrases;
}
答案 0 :(得分:1)
来自documentation of StringTokenizer
:
StringTokenizer是一个遗留类,出于兼容性原因而保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人都使用String的split方法或java.util.regex包。
如果您使用拆分,您可以使用任何正则表达式将文本拆分为句子。您可能需要?!.
中的任何一个以及空格或文本结尾:
text.split("[?!.]($|\\s)")
答案 1 :(得分:0)
这是我对问题的解决方案。
/** tries to decide if a there's a sentence-end in index i of a given text
* @param text
* @param i
* @return
*/
public static boolean isSentenceEnd(String text, int i) {
char c = text.charAt(i);
return isSentenceEndChar(c) && !isPeriodWord(text, i);
}
/**
* PeriodWords are words such as 'Dr.' or 'Mr.'
*
* @param text - the text to examoine.
* @param i - index of the priod '.' character
* @return
*/
private static String[] periodWords = { "Mr.", "Mrs.", "Ms.", "Prof.", "Dr.", "Gen.", "Rep.", "Sen.", "St.",
"Sr.", "Jr.", "Ph.", "Ph.D.", "M.D.", "B.A.", "M.A.", "D.D.", "D.D.S.",
"B.C.", "b.c.", "a.m.", "A.M.", "p.m.", "P.M.", "A.D.", "a.d.", "B.C.E.", "C.E.",
"i.e.", "etc.", "e.g.", "al."};
private static boolean isPeriodWord(String text, int i) {
if (i < 4) return true;
if (text.charAt(i-2) == ' ') return true; // one char words are definetly priodWords
String txt = text.substring(0, i);
for (String pword: periodWords) {
if (txt.endsWith(pword)) return true;
}
if (txt.matches("^.*\\d\\.$")) return true; // dates seperated with "." or numbers with fraction
return false;
}
private static final char[] sentenceEndChars = {'.', '?', '−'};
private static boolean isSentenceEndChar(char c) {
for (char sec : sentenceEndChars) {
if (c == sec) return true;
}
return false;
}