2014-09-27 3 views
0

Я писал регулярное выражение, которое позволяет мне сопоставлять утверждения if/elseif/else. У меня есть, насколько я могу (сопоставление инструкции if/else) с помощью сообщества Stack Overflow.Соответствие if/elseif/else с регулярным выражением

Это содержание Я пытаюсь соответствовать:

{?if gender = male}You're a guy!{?elseif gender = female}You're a gal!{?else}{#gender|capitalise}{?endif} 

(Решение я и добиваюсь позволит неограниченный «ElseIf» заявления, желательно). Он также должен быть в состоянии соответствовать следующее, чтобы убедиться, что он имеет обратную совместимость:

{?if gender = male}Male{?else}Female{?endif} 
{?if gender != female}{#gender}{?endif} 

выход Я ищу:

0: gender = male 
1: You're a guy! 
2: {?elseif gender = female}You're a gal! 
3: {#gender|capitalise} 

Номер 2 должен иметь каждый ElseIf в той же строке, чтобы они могли быть разделены и обработаны после, как:

2: {?elseif gender = female}You're a gal!{?elseif this = that}Output (...) 

Мой текущий регулярное выражение близко, но не достаточно хорошо.

{\?if ([^{}]+)}(.+?)(?:{\?else}(.+?))?{\?endif} 

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

+2

Нет, если они вложены. – Bergi

+0

Это немного язык, и вы не должны пытаться его анализировать с помощью регулярных выражений. – 2014-09-27 17:05:11

+0

Что вы предложите вместо регулярных выражений @torazaburo? Я не мог найти лучшего способа сделать это с моим ограниченным навыком в JavaScript (и я не знал, где спросить, как это сделать!) – Forest

ответ

1

Он не поддерживает вложенные операторы, но попробуйте это:

{\?if ([^{}]+)}(.*?)({\?elseif [^{}]+}.*?)*(?:{\?else}(.+?))?{\?endif} 

Группа 2 будет захватить пустую строку, если нет {?elseif} заявления. Группа 3 не будет существовать, если нет {else}.

See demo.

Объяснение:

{\?if // match "{?if " literally 
([^{}]+)// capture the condition in group 0 
}// match "}" 
(.*?)// capture the content of the {if} branch in group 1 
(// in group 2,... 
    {\?elseif //...capture "{?elseif "... 
    [^{}]+//...a condition... 
    }//..."}"... 
    .*?// and the content of the {elseif} branch... 
)*//...as often as possible. 
(?:// if possible,... 
    {\?else}//...match "{?else}"... 
    (.+?)//...and the content of the {else} branch. 
)? 
{\?endif}// finally, match "{?endif}". 
+0

Это близко к тому, что я искал, но, похоже, это не сработало для меня - он не смог правильно захватить несколько elseifs, если у них был '{#gender | capize}' внутри них. – Forest

+0

'{? If foo} bar {? Elseif cond1} {# gender | capize} {? Elseif cond2} {# gender | capitalize} {? Endif}' правильно захватывает '{? Elseif cond1} {# gender | capize} { ? elseif cond2} {# gender | capitalize} '. Вы положили {#gender | capitalize} как условие? Шаблон не позволяет фигурные скобки {} внутри условия. –

+0

Мне очень жаль, я думаю, что неправильно понял! Это то, что я искал, моя ошибка. Я приму свой ответ, спасибо. – Forest

2

Не уверен, если это квалифицируется как «ответ», но так как вы пишете шаблоны, почему бы не использовать язык шаблонов, из которых есть приблизительно тысяча. Даже если вам нужно было настраивать/расширять их, это было бы проще, чем писать и поддерживать кучу реггептов спагетти.

{{#if gender = 'male'}}You're a guy! 
    {{elsif gender = 'female'}}You're a gal! 
    {{else}}{{gender|capitalise} 
{{/if}} 

Вышеупомянутый язык шаблонов, созданный на рулевом колесе.

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

+0

Я изучаю учебники по написанию парсера, на самом деле кажется, что это будет очень ценное умение, поэтому я буду продолжать писать свои собственные. Но я определенно попытаюсь избежать использования регулярных выражений. – Forest

Смежные вопросы