Для разбора команд плеера я чаще всего использовал метод split, чтобы разделить строку по разделителям, а затем просто вычислить остальные по серии if
s или switch
es. Какие есть несколько способов разбора строк в Java?
Я предполагаю, что вы пытаетесь сделать командный интерфейс максимально простительным. Если это так, я предлагаю вам использовать алгоритм, подобный следующему:
- Читать в строке
- Разбейте строку на токены
- Используйте словарь для преобразования синонимов в общую форму
- Например, преобразуйте «hit», «punch», «strike» и «kick» все в «hit»
- Выполнять действия на неупорядоченной, инклюзивной основе
- Неупорядоченный - «ударить обезьяну по лицу» - то же самое, что и «удар по обезьяне»
- Включено - если предполагается, что команда «ударит обезьяну по лицу», и они предоставляют «ударную обезьяну», вы должны проверить, сколько команд соответствует этому. Если только одна команда, выполните это действие. Это может быть даже хорошей идеей иметь командные приоритеты, и даже если бы даже были совпадения, это могло бы выполнить главное действие.
Мне очень нравятся регулярные выражения. Пока строки команд довольно просты, вы можете написать несколько регулярных выражений, которые могут занять несколько страниц кода для анализа вручную.
Я бы посоветовал вам проверить http://www.regular-expressions.info для хорошего введения в регулярные выражения, а также конкретные примеры для Java.
Простой токенайзер строк на пробелах должен работать, но есть действительно много способов сделать это.
Вот пример использования токенизатора:
String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;
if (tokens.hasMoreTokens()) {
action = tokens.nextToken();
}
if (action != null) {
doCommand(action, tokens);
}
Затем токены могут быть использованы для аргументов. Все это предполагает, что в аргументах не используются пробелы ... так что вы можете использовать свой собственный простой механизм синтаксического анализа (например, получить первый пробел и использовать текст перед тем как действие, или использовать регулярное выражение, если вы не против скорость удара), просто абстрагируйте его, чтобы его можно было использовать где угодно.
Я хотел бы посмотреть на Java миграции в Zork , и склоняются к более простой Natural Language Processor (управляемый либо tokenizing или регулярное выражение) , например, следующее (по этой ссылке):
public static boolean simpleNLP (строка ввода, ключевые слова строки []) { int i; int maxToken =words.length; int to, from; if (inputline.length () = inputline.length ()) возвращает false; // проверка на наличие пустых и пустых строк пока (до> = 0) { to = inputline.indexOf ('', from); если (до> 0) { lexed.addElement (inputline.substring (от, до)); от = до; while (inputline.charAt (from) == '' && from =words.length) {status = true; ломать;} } } возврат статуса; }
...
Все, что дает программисту повод снова взглянуть на Зорка, хорошо в моей книге, просто следи за Грюсом.
...
@CodingTheWheel Вот ваш код, немного почистить и через затмение ( ctrl+ shift+ f) и вставить сюда :)
Включая четыре пробела перед каждой строкой.
public static boolean simpleNLP(String inputline, String keywords[]) {
if (inputline.length() < 1)
return false;
List<String> lexed = new ArrayList<String>();
for (String ele : inputline.split(" ")) {
lexed.add(ele);
}
boolean status = false;
to = 0;
for (i = 0; i < lexed.size(); i++) {
String s = (String) lexed.get(i);
if (s.equalsIgnoreCase(keywords[to])) {
to++;
if (to >= keywords.length) {
status = true;
break;
}
}
}
return status;
}
Когда разделитель String для команды всегда одинаковый String или char (например, ";"), y рекомендуется использовать класс StrinkTokenizer:
но когда разделитель изменяется или является сложным, y рекомендуют использовать регулярные выражения, которые могут использоваться самим классом String, метод split, начиная с версии 1.4. Он использует класс Pattern из пакета java.util.regex
Sun сама рекомендует держаться подальше от StringTokenizer и использовать вместо этого метод String.spilt.
Вы также захотите взглянуть на класс Pattern.
Разбор вручную - это очень весело ... в начале :)
На практике, если команды не очень сложные, вы можете обращаться с ними так же, как те, что используются в интерпретаторах командной строки. Есть список библиотек, которые вы можете использовать: http://java-source.net/open-source/command-line . Я думаю, что вы можете начать с Apache Commons CLI или args4j (использует аннотации). Они хорошо документированы и действительно просты в использовании. Они обрабатывают синтаксический анализ автоматически, и единственное, что вам нужно сделать, это прочитать определенные поля в объекте.
Если у вас есть более сложные команды, возможно, было бы лучше создать формальную грамматику. Существует очень хорошая библиотека с графическим редактором, отладчиком и интерпретатором для грамматики. Он называется ANTLR (и редактор ANTLRWorks ) и он бесплатный :). Есть также несколько примеров грамматик и учебных пособий.
Если это для анализа командных строк, я бы предложил использовать Commons Cli .
Библиотека CLI Apache Commons предоставляет API для обработки интерфейсов командной строки.
Еще один голос за ANTLR / ANTLRWorks. Если вы создадите две версии файла, одну с Java-кодом для фактического выполнения команд, а другую без (только с грамматикой), то у вас будет исполняемая спецификация языка, которая отлично подходит для тестирования, а не для документации и большая экономия времени, если вы когда-нибудь решите портировать его.
Попробуйте JavaCC генератор парсера для Java.
Он имеет множество функций для интерпретации языков и хорошо поддерживается в Eclipse.
Если язык мертв, просто как
ГЛАГОЛ СУЩЕСТВИТЕЛЬНОЕ
тогда раскол вручную работает хорошо.
Если он более сложный, вам стоит обратить внимание на такой инструмент, как ANTLR или JavaCC.
У меня есть учебник по ANTLR (v2) по адресу http://javadude.com/articles/antlrtut, который даст вам представление о том, как это работает.
JCommander выглядит неплохо, хотя я еще не тестировал его.
Если ваш текст содержит разделители, вы можете использовать свой split
метод.
Если текст содержит нерегулярные строки, значит, в нем другой формат, тогда вы должны использовать regular expressions
.
Метод split может разбить строку на массив указанного выражения подстроки regex
. Его аргументы в двух формах, а именно: split ( String regex
) и split ( String regex, int limit
), для чего split ( String regex
) фактически вызывается split (String regex, int limit) для достижения, limit равен 0 . Тогда, когда предел> 0 и предел <0 представляют что?
Когда JDK объяснил: когда предел> 0 длины подмассива до предела, то есть, если возможно, может быть подразделом limit-1 , оставаясь в качестве подстроки (за исключением предела-1 раз, когда символ имеет конец строки) ;
limit <0 указывает отсутствие ограничения на длину массива;
limit = 0 конец строки пустая строка будет обрезана.
StringTokenizer
Этот класс предназначен для совместимости и является классом прежних версий, поэтому мы должны попытаться использовать метод split класса String. обратитесь к ссылке