StringTokenizer проблема токенизации

String a ="the STRING TOKENIZER CLASS ALLOWS an APPLICATION to BREAK a STRING into TOKENS.  ";

StringTokenizer st = new StringTokenizer(a);
while (st.hasMoreTokens()){
  System.out.println(st.nextToken());

Учитывая приведенные выше коды, вывод следующий:

the
STRING TOKENIZER CLASS
ALLOWS
an
APPLICATION
to
BREAK
a
STRING
into
TOKENS. 

Мой единственный вопрос: почему «STRING TOKENIZER CLASS» был объединен в один токен????????

Когда я пытаюсь запустить этот код,

System.out.println("STRING TOKENIZER CLASS".contains(" "));

Он напечатал забавный результат,

ЛОЖНЫЙ

Звучит не логично, верно? Я понятия не имею, что пошло не так.

Я выяснил причину: пространство каким-то образом не было распознано Java как действительное пространство. Но я не знаю, как это оказалось так, начиная с предварительной обработки и заканчивая кодом, который я опубликовал.

Ребята, мне нужно подчеркнуть, что приведенный ниже код запускается первым перед приведенным выше.

if (!suspectedContentCollector.isEmpty()){ Итератор i =подозреваемыйContentCollector.iterator(); Строка темп=""; в то время как (i.hasNext()){ temp+=i.next().toLowerCase()+ " "; } StringTokenizer st = новый StringTokenizer(temp);

        while (st.hasMoreTokens()){
            temp=st.nextToken();
            temp=StopWordsRemover.remove(temp);
            analyzedSentence = analyzedSentence.replace(temp,temp.toUpperCase());
        }
    }

Следовательно, как только он был изменен на ПРОПИСНЫЕ, что-то где-то пошло не так, и я понял, что не распознаются только определенные пробелы. Может ли это быть причиной извлечения текста из документа?

Следуя коду,

String a ="КЛАСС ТОКЕНИЗАТОРА СТРОКИ ПОЗВОЛЯЕТ ПРИЛОЖЕНИЮ РАЗБИВАТЬ СТРОКУ на ТОКЕНЫ.  "; for (int i: a.toCharArray()) { System.out.print(i + ""); }

произведен следующий вывод,

116 104 101 32 83 84 82 73 78 71 160 84 79 75 69 78 73 90 69 82 160 67 76 65 83 83 32 65 76 76 79 87 83 32 97 110 32 65 80 80 76 73 67 65 84 73 79 78 32 116 111 32 66 82 69 65 75 32 97 32 83 84 82 73 78 71 32 105 110 116 111 32 84 79 75 69 78 83 46 160 32


person Mr CooL    schedule 22.03.2010    source источник
comment
Держу пари, что исходная строка содержит Shift-Space, а не пробел (или какой-либо другой пробел).   -  person Chris Cudmore    schedule 22.03.2010
comment
Я не вижу проблем ... у меня все работает нормально!   -  person jagamot    schedule 22.03.2010
comment
Какую версию java вы используете? На какой платформе?   -  person Enrique    schedule 22.03.2010
comment
@Enrique: JDK1.6 18 Может быть, у меня 2 JDK? JDK1.6 17 и JDK1.6 18   -  person Mr CooL    schedule 22.03.2010


Ответы (5)


Глядя на коды символов, рассматриваемый «пробел» — это 0xA0, который должен быть неразрывным пробелом. Я предполагаю, что это было введено намеренно, чтобы «STRING TOKENIZER CLASS» рассматривался как одно слово.

Решение (если вы действительно считаете правильным разбить «STRING TOKENIZER CLASS» на три слова) состоит в том, чтобы добавить неразрывный пробел в качестве разделителя к классу StringTokenizer (соответственно, метод String.split()). Например.

  new StringTokenizer(string, " \t\n\r\f\240")
person Lars    schedule 22.03.2010

Там -- ответ находится в фрагменте, который вы добавили. Перечисленные целые числа показывают, что пробел после слова STRING представляет собой 160-й символ ASCII, то есть  , вместо 32-го символа, который является обычным пробелом. Отредактируйте исходную строку, заменив пробелы в STRING TOKENIZER CLASS реальными пробелами вместо Shift-пробелов.

Просто побочный комментарий из 1.4.2 Javadoc:

StringTokenizer — это устаревший класс, который сохраняется по соображениям совместимости, хотя его использование в новом коде не рекомендуется. Всем, кто ищет эту функциональность, рекомендуется вместо этого использовать метод разделения String или пакет java.util.regex.

person Jim Kiley    schedule 22.03.2010

Возможно ли, что вы используете что-то отличное от обычных пробелов ascii в «STRING TOKENIZER CLASS»? Может быть, вы удерживали клавишу Shift и вместо этого получили смещенный пробел?

person Paul Tomblin    schedule 22.03.2010
comment
Я думал так же, как и вы.. Но исходная строка была написана строчными буквами.. и я изменил некоторые слова на прописные.. После изменения этой части некоторые пробелы, похоже, не обнаружены, что является очень странным случаем. для меня .. Любая идея, почему ?? - person Mr CooL; 22.03.2010
comment
Вы изменили их на верхний регистр, нажав Caps Lock или удерживая клавишу Shift во время ввода? Если второе, то точка зрения Павла кажется правильной. - person Jim Kiley; 22.03.2010

Сделайте нам всем одолжение и скопируйте и вставьте вывод этого фрагмента:

    for (int i : a.toCharArray()) {
        System.out.print(i + " ");
    }

Хорошо, теперь, глядя на вывод, он подтверждает то, о чем мы все подозревали: эти «пробелы» — это ASCII 160, &nbsp неразрывный пробел. Это символ, отличный от обычного пробела ASCII 32.

Вы можете позволить токенизатору (который, как говорили другие, устарел) включать ASCII 160 в качестве разделителя, или вы можете отфильтровать его из входной строки, если он не должен быть там в первую очередь.

На данный момент a = a.replace((char) 160, (char) 32); перед токенизацией — это быстрое решение.

person polygenelubricants    schedule 22.03.2010
comment
Извините, polygenelubricants, как на самом деле заменить ASCII 160 на обычный пробел ASCII 32? потому что вставленный вами код, a = a.replace(160, 32); не работал. - person Mr CooL; 22.03.2010
comment
Извините, я забыл добавить актерский состав (char). - person polygenelubricants; 22.03.2010

Если вы копируете/вставляете предложение с веб-страницы или документа Word, скорее всего, вместо пробелов у вас есть специальные символы (например, неразрывные пробелы и т. д.). Попробуйте еще раз, напечатав предложение в редакторе Java.

person Olivier Croisier    schedule 22.03.2010
comment
Да... Если я наберу это, проблем не возникнет, однако, если только через какую-то обработку, у него будет эта проблема.... - person Mr CooL; 22.03.2010