2013-09-23 4 views
2

Я пытаюсь использовать регулярное выражение в Delphi для решения директив C PreProcessor. В качестве примера я есть текстовый файл, который содержитДиректива CPP #ifdef Regex Solution

#define test 
#ifdef test 
foo 

#else 

bar 
#endif 

То, что я хочу знать, на мой кулак матча, если это IFDEF или IfNDef.
В моем втором матче я хочу получить, что должно (не) быть определено.
Номер три будет до тех пор, пока не будет #else или #endif.
Если это было #else, #else должно быть содержимым совпадения 4.
Матч 5 будет затем снова заполнен, а совпадение 6 будет содержать #endif
BTW. Меня не волнует \ n или \ r в матчах. Они будут отфильтрованы.

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

/#(ifn?def) +(.*)\n(.*)(#else)?(.*)?(#endif)/si 

, который сделал абсолютно не работает. И независимо от того, что я пытаюсь, я могу получить только #ifdef и ключ, который должен (не) быть определен + все остальное во втором матче.

Есть ли решение для регулярных выражений? Является ли regex лучшим решением для такого рода вещей?

+2

Регулярное выражение почти наверняка не лучшее решение для вашей проблемы. Например, как вы собираетесь обрабатывать гнездование? Если вам нужен синтаксический анализатор, напишите парсер. –

+0

@ Карл Норум: На самом деле я знаю, что не будет гнездования - по крайней мере пока. Что ж. Я надеялся на простое решение регулярных выражений. Если их нет, мне придется написать парсер. –

ответ

3

Поскольку подвыражения 4 и 5 являются необязательными, жадные второе и третье подвыражения в конечном итоге поглощают все, даже если на вашем входе отображается #else. Вы должны сделать их неживыми. Чтобы гарантировать, что подвыражение 5 заполняется только в том случае, если подвыражение 4 соответствует, поместите его внутри другого. Вы будете в конечном итоге с этим:

/#(ifn?def) +(.*?)\n(.*?)(#else(.*))?(#endif)/si 

Я бы Подвыражение 4 а , не захватывая группу, и я бы не стал группировать подвыражения 6 вообще, так как содержимое обоих можно судить по контексту.