Соответствие шаблону Lua для извлечения жестко закодированных строк в базе кода

Я работаю с базой кода C++. Прямо сейчас я использую код на C++, вызывающий скрипт lua, чтобы просмотреть всю базу кода и, надеюсь, вернуть список всех строк, которые используются в программе.

Рассматриваемым строкам всегда предшествует макрос JUCE, называемый TRANS. Вот несколько примеров, которые должны извлечь строку

TRANS("Normal")
TRANS ( "With spaces" )
TRANS("")
TRANS("multiple"" ""quotations")
TRANS(")")
TRANS("spans \
multiple \
lines")

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

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

path = ...

--Open file and read source into string
file = io.open(path, "r")
str = file:read("*all")

и называется

for word in string.gmatch(string, 'TRANS%s*%b()') do print(word) end

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

Однако это не работает для строк, которые вызывают дисбаланс в скобках. напримерTRANS(")") вернусь TRANS("), вместо TRANS("(")

Я пересмотрел свой шаблон

for word in string.gmatch(string, 'TRANS%s*(%s*%b""%s*') do print(word) end

где шаблон должен начинаться с TRANS, затем 0 или нескольких пробелов. Тогда он должен иметь (символ, за которым следует ноль или более пробелов. Теперь, когда мы находимся в скобках, у нас должно быть сбалансированное количество "" знаков, за которыми следуют еще 0 или много пробелов, и, наконец, заканчивается буквой a). К сожалению, это не возвращает единственное значение при использовании. Но... Я думаю, что даже если бы это сработало так, как я ожидал... Может быть \" внутри, что вызывает несбалансированность кронштейна.

Любой совет по извлечению этих строк? Должен ли я продолжать пытаться найти последовательность соответствия шаблону? или я должен попробовать прямой алгоритм... Знаете ли вы, почему мой второй шаблон не вернул строки? Любой другой совет! Я не собираюсь покрывать 100% всех возможностей, но быть близким к 100% было бы здорово. Спасибо!:D

2 ответа

Решение

Во втором случае вы забыли избежать скобок. Пытаться

for word in string.gmatch(str, 'TRANS%s*%(%s*(%b"")%s*%)') do print(word) end

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

Другие вопросы по тегам