-2

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

我的问题是,当我使用 new 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);
    }
}
4

1 回答 1

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[]{"",""};
    }

希望这能解决您的问题。

于 2013-02-13T05:10:22.983 回答