Разбить текстовый скрипт на подстроки по шаблону - PullRequest
1 голос
/ 14 октября 2010

Рассмотрим следующий скрипт (это полная чушь на псевдо-языке):

if (Request.hostMatch("asfasfasf.com") && someString.existsIn(new String[] {"brr", "hrr"}))   {
    if (Requqest.clientIp("10.0.x.x")) {
        somevar = "1";
    }
    somevar = "2";
}
else {
    somevar = "first";
}
string foo = "foo";
// etc. etc.

Как бы вы взяли из него параметры и содержимое if-блока? Блок if имеет формат:

if<whitespace>(<parameters>)<whitespace>{<contents>}<anything>

Я пытался использовать String.split() с шаблоном регулярных выражений ^if\s*\(|\)\s*\{|\}\s*, но это с треском провалилось. А именно, проблема в том, что ) { находится также во внутреннем блоке if, и закрывающий } также находится во многих местах. Я не думаю, что ни ленивое, ни энергичное расширение здесь не работает.

Итак ... какие-нибудь указатели на то, что мне может понадобиться здесь, чтобы реализовать это с помощью регулярных выражений?

Мне также нужно получить оставшуюся строку без кода блока if (поэтому код начинается с else { ...). Использование только String.split() кажется затруднительным, поскольку нет информации о длине частей, которые были проанализированы.

Я изначально создал решение на основе циклов (интенсивно используя String.substring()) для этого, но оно скучно. Я хотел бы иметь что-то более изумительное вместо этого. Должен ли я использовать регулярное выражение или создать пользовательскую универсальную функцию (есть много других случаев, кроме этой), которая вместо этого использует анализируемую строку и шаблон (рассмотрим шаблон if<whitespace>(... выше)?

Редактировать : Изменен возврат к назначению переменных, поскольку в противном случае это не имело бы смысла.

Ответы [ 3 ]

2 голосов
/ 14 октября 2010

Вам было бы гораздо лучше использовать (или написать) парсер, чем пытаться сделать это с помощью Regex.

Regex отлично подходит для чего-то, но для сложного разбора, подобного этому, это отстой. Еще один пример, где отстой, который здесь часто задают, - это анализ HTML - вы можете сделать это в ограниченной степени, но для чего-то сложного анализатор DOM является гораздо лучшим решением.

Для [очень] простого парсера вам нужна рекурсивная функция, которая ищет фигурные скобки { и }, рекурсивно понижая уровень каждый раз, когда сталкивается с открывающей фигурной скобкой, и возвращаясь обратно на уровень когда он находит закрывающую скобку. Затем необходимо сохранить содержимое строки между двумя фигурными скобками на каждом уровне.

1 голос
/ 14 октября 2010

В соответствии с вышесказанным вам понадобится парсер. Одним из типов, который легко реализовать (и интересно писать), является парсер рекурсивного спуска с возвратом . Существует также множество генераторов синтаксических анализаторов, хотя у большинства из них есть кривая обучения. Один дружественный к Java генератор синтаксических анализаторов - JavaCC .

1 голос
/ 14 октября 2010

Обычный язык не будет работать, потому что обычная грамматика не может соответствовать таким вещам, как «любое количество открытых скобок, за которыми следует любое количество закрытых скобок».Для этого потребуется контекстно-свободная грамматика .

Если вы не используете контекстно-свободный грамматический анализатор для Java или расширение регулярного выражения, которое делаетрегулярные выражения больше не являются регулярными , ваше решение на основе циклов, вероятно, самое модное решение.

...