Разбор игровых консольных команд? - PullRequest
3 голосов
/ 13 января 2012

Мне нужно иметь возможность обрабатывать данные, которые могут выглядеть следующим образом:

set setting1 "bind button_x +actionslot1;bind button_y \" bind button_x +stance \" "

bind button_a jump

set setting2 1 1 0 1

toggle setting_3 " \"value 1\" \"value 2\" \"value 3\" "

Вот как выглядят некоторые команды для консоли игры, и я пытаюсь написать своего рода эмулятор, который будет интерпретировать код так же, как игра.

Первое, что приходит на ум, это регулярное выражение, но я не уверен, что это лучший вариант. Например, при сопоставлении значения параметра я мог бы попробовать что-то вроде /set [\w_]+ "?(.+)"?/, но подстановочный знак совпадает с конечной кавычкой, потому что она не ленивая, но если я сделаю ее ленивой, она будет соответствовать кавычке внутри значения. Если я сделаю его жадным и перестану сопоставлять кавычки, он не будет соответствовать экранированным кавычкам в значениях.

Даже если существуют возможные решения для регулярных выражений, они кажутся неправильным вариантом. Ранее я спрашивал о том, как такие программы, как Visual Studio и Notepad ++, знают, какие скобки и фигурные скобки соответствуют друг другу, и мне сказали, что в некоторых отношениях есть нечто похожее на регулярное выражение, но гораздо более мощное.

Единственное, о чем я могу думать, - это проходить строки кода за символом и использовать логические значения для определения этого состояния текущего символа.

Какие у меня есть варианты? Что разработчики игр используют для обработки команд консоли?

edit: Вот еще одна возможная команда, которая сильно удерживает меня от использования регулярных выражений:

set setting4 "bind button_a \" bind button_b "\" set setting1 0 \" " \" "

Команды включают не только экранированные кавычки, но и цитаты типа "\" внутри экранированных кавычек.

Ответы [ 2 ]

2 голосов
/ 13 января 2012

Я бы посоветовал вам прочитать о Лексическом анализе , это процесс токенизации вашего текста с использованием грамматики.Я думаю, что это поможет вам с тем, что вы пытаетесь сделать.

2 голосов
/ 13 января 2012

Я не хочу держать вас на пути регулярных выражений - вы правы в том, что существуют решения не-регулярных выражений, которые могут быть более подходящими (я просто не знаю, каковы они). Тем не менее, вот одно из возможных регулярных выражений, которое должно решить проблему с кавычками:

/set [\w_]+ "?((\\"|[^"])+)"?/

Я изменил .+ на (\\"|[^"])+. В основном это совпадения \" ИЛИ всего, что не является кавычкой. Другими словами, он будет соответствовать чему угодно, кроме кавычек, которые не экранированы.

Опять же, если кто-то может предложить более сложное решение без регулярных выражений, вы должны строго рассмотреть его.

Редактировать: Обновленный пример, который вы предоставили, нарушает это решение, и я думаю, что это нарушит любое решение регулярных выражений.

Редактировать 2: Вот версия вашего регулярного выражения на C #. Он использует @, чтобы сказать компилятору обрабатывать строку как дословный литерал , что означает, что он игнорирует \ как escape-символ. Единственное предостережение в том, что для представления " в дословном литерале вы должны набрать его как "", но это все же лучше, чем иметь косую черту везде. Учитывая преобладание escape-последовательностей в регулярных выражениях, я рекомендую использовать дословные литералы везде, где требуется вводить регулярное выражение в строке.

string pattern = @"set [\w_]+ ""?((\\""|[^""])+)""?"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...