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

1

У меня очень простой токенизатор, использующий 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;
  • 0
    Я не вижу того, что вы видите. Если я передам в T_1 , я получу это в качестве вывода: [null, T, 1.0]
  • 0
    Я чувствую, что wordChars каким-то образом связан с ответом, но я не могу понять, как добавить слово char. Похоже, вы можете только установить диапазон. Удивительно плохая документация и API для класса Java, IMO. Есть ли законная причина, по которой вы используете StreamTokenizer StringTokenizer ?
Показать ещё 3 комментария
Теги:
split
stringtokenizer
tokenize

2 ответа

3
Лучший ответ

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

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]
  • 0
    Отлично! Это на самом деле сделало это для меня. Просто выбросить эту строку прямо под токенизатор
  • 0
    Для других я настроил это, чтобы показать, что вы можете вызывать wordChars несколько раз, и он учитывает каждый вызов, а не только самый последний. Это довольно необычно, как это не задокументировано в Javadoc.
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]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню