Соответствие шаблону 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 прекрасно справится с вашими потребностями.