解析器遗漏了最后一个字 - Java

时间:2013-02-13 04:26:56

标签: java debugging parsing

这是一个自定义构建的解析器,因为我真的不喜欢默认java.util.Scanner的工作方式。

我的问题是,当我使用新的Parser(“Parsed phrase here”)或函数reloadBuffer(“Parsed phrase here”)创建解析器时,它会错过输入的最后一个单词。我试图让这段代码尽可能地可读,但它仍然非常密集,对不起。哦,如果这个问题得到解决,请随意使用它。

import java.util.*;

public class Parser
{

    public static char letters[] = new char[]{'q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'};
    public static char numbers[] = new char[]{'0','1','2','3','4','5','6','7','8','9'};

    public ArrayList<String> words;
    public String buffer;
    public int wordIndex;
    /**
     * Assembles an empty parser.
     */
    public Parser()
    {
        words = new ArrayList<String>();
        buffer = "";
        wordIndex = 0;
    }
    /**
     * Assembles the Parser with given String as input. Uses reloadBuffer();
     * @see reloadBuffer
     */
    public Parser(String input)
    {
        words = new ArrayList<String>();
        reloadBuffer(input);
    }
    /**
     * Parses each word/set of chars into the array. Must be called before any retreiving of words can be done. 
     * This is basically the core function of the class. Be very careful if you edit this part.
     */
    public void parseBuffer(){
        String input = buffer;
        while(input.length()>=1)
        {
            input = trimToSelectedChars(input);
            words.add(removeFirstSet(input)[0]);
            input = removeFirstSet(input)[1];
        }
    }
    /**
     * Resets the array with given String as input. Used in the primary constructor. Uses parseBuffer();
     * @see parseBuffer()
     */
    public void reloadBuffer(String input){
        buffer = input;
        wordIndex = 0;
        parseBuffer();
    }

    /**
     * @return the next word parsed from the string, based upon the value of wordIndex.
     */
    public String next(){
        wordIndex++;
        if (wordIndex<= words.size()+1){
            try {return words.get(wordIndex-1);
            } catch(Exception ex) {
                System.err.println("Error: reached end of list. Resetting index to 0.");
                resetIndex();
            }
        }
        return "";
    }

    //Notice that when using wordAt(), it leaves the index where you selected, and it does not revert to where it was before.
    /**
     * @return the word at indicated index, much like the charAt() function, using the next() function. Also sets wordIndex to input index.
     * @see String
     * @see next()
     */
    public String wordAt(int index){
        wordIndex = index;
        return next();
    }

    /**
     * @return the first word parsed from the input.
     * @see String
     */
    public String firstWord()

    {
        return wordAt(0);
    }

    /**
     *Be careful in using lastWord() as it sets the wordIndex to the last value which will return a String
     *@return the last parsed word from the input.
     */
    public String lastWord(){
        return wordAt(words.size()-1);
    }

    /**
     * Resets the wordIndex to 0, the beginning.
     */
    public void resetIndex(){wordIndex = 0;}

    /**
     * return whether or not there is another word in the parser list.
     */
    public boolean hasNext(){
        return (wordIndex<words.size());
    }
    //internal methods here.
    private String[] removeFirstSet(String input)
    //removes the first set of adjecent letters from a string, and returns it.
    {
        String[] words = new String[2];
        int index = 0;
        if(input.length()<1) words[0] = "";
        while(index<input.length()){
            //this loop to retrieve the first word.
            if(isLetter(input.charAt(index))||isNumber(input.charAt(index))){
                index++; //if the first char is a letter, move on to the next one.
            }
            else{
                words[0]=input.substring(0,index);
                words[1]=input.substring(index);
                return words;
            }
        }
        return new String[]{"",""};
    }

    private String trimToSelectedChars(String input)
    //trims anything that is not a letter from the front of a String.
    {
        input = input.trim();
        while(input.length()>0){
            //this loop to clear up junk before the input.
            if(isLetter(input.charAt(0))||isNumber(input.charAt(0))){
                break; //if the first char is a letter or a number, break the loop
            }
            else input=input.substring(1);// else cut the first char off the string.
        }
        return input;
    }

    private boolean isLetter(char c)
    //returns whether or not the indicated char is an alphabetical letter.
    {
        for(int i = 0; i<letters.length; i++){
            if(letters[i]==c)return true;
        }
        return(false);
    }

    private boolean isNumber(char c)
    //returns whether or not the indicated char is a number.
    {
        for(int i = 0; i<numbers.length; i++){
            if(numbers[i]==c)return true;
        }
        return(false);
    }
}

1 个答案:

答案 0 :(得分:0)

用以下方法替换方法removeFirstSet

private String[] removeFirstSet(String input)
    //removes the first set of adjecent letters from a string, and returns it.
    {
        String[] words = new String[2];
        int index = 0;
        if(input.length()<1) words[0] = "";
        while(index<input.length()){
            //this loop to retrieve the first word.
            if( isLetter(input.charAt(index))||isNumber(input.charAt(index))){
                index++; //if the first char is a letter, move on to the next one.
            }
            else{ 
                words[0]=input.substring(0,index);
                words[1]=input.substring(index);
                return words;
            }
        }
        if(index==input.length()){
             words[0]=input.substring(0,index);
             words[1]=input.substring(index);
             return words;
        }
        return new String[]{"",""};
    }

希望这能解决您的问题。