Я использую Java StreamTokenizer для извлечения различных слов и чисел Строки, но столкнулся с проблемой, где числа, которые включают запятые, затронуты, например, 10,567 читается как 10,0 и, 567.
Я также должен удалить все нечисловые символы из чисел, где они могли бы произойти, например, 678,00$ должны быть 678.00, или-87 должен быть 87.
Я полагаю, что они могут быть достигнуты через пробел и wordChars методы, но у кого-либо есть какая-либо идея, как сделать это?
Основной код streamTokenizer в настоящее время:
BufferedReader br = new BufferedReader(new StringReader(text));
StreamTokenizer st = new StreamTokenizer(br);
st.parseNumbers();
st.wordChars(44, 46); // ASCII comma, - , dot.
st.wordChars(48, 57); // ASCII 0 - 9.
st.wordChars(65, 90); // ASCII upper case A - Z.
st.wordChars(97, 122); // ASCII lower case a - z.
while (st.nextToken() != StreamTokenizer.TT_EOF) {
if (st.ttype == StreamTokenizer.TT_WORD) {
System.out.println("String: " + st.sval);
}
else if (st.ttype == StreamTokenizer.TT_NUMBER) {
System.out.println("Number: " + st.nval);
}
}
br.close();
Или кто-то мог предложить, чтобы REGEXP достиг этого? Я не уверен, полезен ли REGEXP здесь, учитывая, что любое разделение произошло бы после того, как маркеры читаются из строки.
Спасибо
Г-н Morgan.
StreamTokenizer устарел, лучше использовать Scanner , это пример кода для вашей проблемы:
String s = "$23.24 word -123";
Scanner fi = new Scanner(s);
//anything other than alphanumberic characters,
//comma, dot or negative sign is skipped
fi.useDelimiter("[^\\p{Alnum},\\.-]");
while (true) {
if (fi.hasNextInt())
System.out.println("Int: " + fi.nextInt());
else if (fi.hasNextDouble())
System.out.println("Double: " + fi.nextDouble());
else if (fi.hasNext())
System.out.println("word: " + fi.next());
else
break;
}
Если вы хотите использовать запятую в качестве разделителя с плавающей запятой, используйте fi.useLocale (Locale.FRANCE);
Попробуйте так:
String sanitizedText = text.replaceAll("[^\\w\\s\\.]", "");
SanitizedText будет содержать только алфавитно-цифровые символы и пробелы; токенизация после этого должна быть легкой.
EDIT
Отредактировано для сохранения десятичной точки (в конце скобки). .
является "специальным" для regexp, поэтому ему нужна обратная косая черта.
Конечно, это можно сделать с помощью regexp:
s/[^\d\.]//g
Однако обратите внимание, что он съедает все запятые, что, вероятно, именно то, что вам нужно, если использовать американский числовой формат, где запятая разделяет только тысячи. В некоторых языках в качестве десятичного разделителя вместо точки используется запятая. Так что будьте осторожны при анализе международных данных.
Я предоставляю вам перевести это на Java.