Java Tokenization: трактуйте все, что разделено подчеркиванием, как одно слово

У меня есть очень простой токенизатор, использующий StreamTokenizer, который преобразует математические выражения в их отдельные компоненты (ниже). Проблема, с которой я столкнулся, заключается в том, что если в выражении есть переменная T_1, она разделится на [T,_,1], которую я хотел бы вернуть как [T_1].

Я попытался использовать переменную, чтобы проверить, был ли последний символ подчеркивания, и, если это так, добавить подчеркивание в список. Размер-1, но это выглядит как очень неуклюжее и неэффективное решение. Есть ли способ сделать это? Спасибо!

        StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(s));
        tokenizer.ordinaryChar('-'); // Don't parse minus as part of numbers.
        tokenizer.ordinaryChar('/'); // Don't parse slash as part of numbers.
        List<String> tokBuf = new ArrayList<String>();
        while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) //While not the end of file 
        {
            switch (tokenizer.ttype) //Switch based on the type of token
            {
            case StreamTokenizer.TT_NUMBER: //Number
                tokBuf.add(String.valueOf(tokenizer.nval));
                break;
            case StreamTokenizer.TT_WORD: //Word
                tokBuf.add(tokenizer.sval);
                break;
            case '_':
                tokBuf.add(tokBuf.size()-1, tokenizer.sval);
                break;
            default: //Operator
                tokBuf.add(String.valueOf((char) tokenizer.ttype));
            }
        }

        return tokBuf;

2 ответа

Решение

Это то, что вы хотите.

tokenizer.wordChars('_', '_');

Это делает _ узнаваемым как часть слова.

Дополнения:

Это строит и запускает:

public static void main(String args[]) throws Exception {
    String s = "abc_xyz abc 123 1 + 1";
    StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(s));
    tokenizer.ordinaryChar('-'); // Don't parse minus as part of numbers.
    tokenizer.ordinaryChar('/'); // Don't parse slash as part of numbers.
    tokenizer.wordChars('_', '_'); // Don't parse slash as part of numbers.


    List<String> tokBuf = new ArrayList<String>();
    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) //While not the end of file 
    {
        switch (tokenizer.ttype) //Switch based on the type of token
        {
        case StreamTokenizer.TT_NUMBER: //Number
            tokBuf.add(String.valueOf(tokenizer.nval));
            break;
        case StreamTokenizer.TT_WORD: //Word
            tokBuf.add(tokenizer.sval);
            break;
        default: //Operator
            tokBuf.add(String.valueOf((char) tokenizer.ttype));
        }
    }
    System.out.println(tokBuf);
}

run:
[abc_xyz, abc, 123.0, 1.0, +, 1.0]

StringTokenizer может быть лучше. Если так, вот как вы это используете:

import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer;

public class Solution {

    public static void main(String args[]) throws Exception {
        StringTokenizer tokenizer = new StringTokenizer("T_1 1 * bar");
        List<String> tokBuf = new ArrayList<String>();
        while (tokenizer.hasMoreTokens()) //While not the end of file
        {
            tokBuf.add(tokenizer.nextToken());
        }

        System.out.println(tokBuf);
    }
}

Это распечатано:

[T_1, 1, *, bar]
Другие вопросы по тегам