Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何识别句子的结尾_Java_Regex_Nlp_Tokenize - Fatal编程技术网

Java 如何识别句子的结尾

Java 如何识别句子的结尾,java,regex,nlp,tokenize,Java,Regex,Nlp,Tokenize,如果我有上面的字符串,我需要通过使用句子边界标点(比如.和?)将其分解成句子 但它不应该因为有一个指针而将句子拆分为6。有没有办法确定java中正确的句子边界位置?我曾尝试在java.util包中使用stringTokenizer,但每当它找到指针时,它总是打断句子。有人能给我一个正确的方法吗 这是我尝试过的将文本标记成句子的方法 String x=" i am going to the party at 6.00 in the evening. are you coming with me?"

如果我有上面的字符串,我需要通过使用句子边界标点(比如.和?)将其分解成句子

但它不应该因为有一个指针而将句子拆分为6。有没有办法确定java中正确的句子边界位置?我曾尝试在java.util包中使用stringTokenizer,但每当它找到指针时,它总是打断句子。有人能给我一个正确的方法吗

这是我尝试过的将文本标记成句子的方法

String x=" i am going to the party at 6.00 in the evening. are you coming with me?";
公共静态数组列表句子切分器(字符串文本){
ArrayList语句=新的ArrayList();
StringTokenizer st=新的StringTokenizer(文本“.?!”);
而(st.hasMoreTokens()){
添加(st.nextToken());
}
返回句子;
}
我还有一种方法可以将句子分割成短语,但在这里,当程序发现逗号(,)时,它会分割文本。但是,当中间有逗号的60000个数字时,我不需要拆分它。下面是我用来分割短语的方法

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;
}
publicstaticarraylistphrasesegmenter(字符串文本){
ArrayList短语=新建ArrayList();
StringTokenizer st=新的StringTokenizer(文本“,”);
而(st.hasMoreTokens()){
添加(st.nextToken());
}
返回短语;
}
来自:

StringTokenizer是一个遗留类,尽管新代码中不鼓励使用它,但出于兼容性原因保留它。建议任何寻求此功能的人改用String的split方法或java.util.regex包

如果使用split,可以使用任何正则表达式将文本拆分为句子。您可能想要类似于
和空格或文本结尾:

   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;
}

这是我解决这个问题的办法

text.split("[?!.]($|\\s)")
/**尝试确定给定文本的索引i中是否有句子结尾
*@param text
*@param i
*@返回
*/
公共静态布尔值isSentenceEnd(字符串文本,int i){
char c=text.charAt(i);
返回ISENTENCENDCHAR(c)和&!isPeriodWord(文本,i);
} 
/**
*周期词是诸如“Dr.”或“Mr.”之类的词
*
*@param text-要添加到examoine的文本。
*@param i-priod.'字符的索引
*@返回
*/
私有静态字符串[]periodWords={“先生”、“太太”、“女士”、“教授”、“博士”、“将军”、“代表”、“参议员”、“圣徒”,
“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.”,
“即”、“等”、“如”、“等”;
私有静态布尔值isPeriodWord(字符串文本,int i){
如果(i<4)返回true;
如果(text.charAt(i-2)=''返回true;//一个字符的单词肯定是优先单词
String txt=text.substring(0,i);
for(字符串pword:periodWords){
if(txt.endsWith(pword))返回true;
}
如果(txt.matches(“^.*\\d\\.$”)返回true;//日期以“.”分隔或数字以分数分隔
返回false;
}
私有静态最终字符[]语句EndChars={'.','?','−'};
私有静态布尔值isSentenceEndChar(char c){
for(字符集:SENTENDCHARS){
如果(c==sec)返回true;
}
返回false;
}

但是如何识别正确的位置来分割句子。如果句子中有一个小数,那么句号不能作为句子的结尾。我需要知道如何处理这些情况。r(
\s
)并在开头添加了一个
*?
,以使拆分后返回的第一个元素更清晰。我仍然没有得到答案。@fejese您的正则表达式不起作用@fejese谢谢,伙计。它现在起作用了。但是我有另一个问题,我编辑了我的帖子。您能检查一下并给我一个解决方案吗?非常感谢。如果您发现我的答案适合你的问题,然后接受它,如果你有额外的新问题,那么打开一个新的问题。但是你最近的问题与原来的问题完全相同。花一些时间来理解这个答案中的解决方案为什么和如何工作,并且应该非常简单地将其适应你的新问题。你需要使用sentence拆分器。请参阅相关问题:
/** 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;
}