У меня есть это [противное] регулярное выражение для захвата сигнатуры процедуры VBA со всеми частями в ведре:
public static string ProcedureSyntax
{
get
{
return
@"(?:(?<accessibility>Friend|Private|Public)\s)?(?:(?<kind>Sub|Function|Property\s(Get|Let|Set)))\s(?<identifier>(?:[a-zA-Z][a-zA-Z0-9_]*)|(?:\[[a-zA-Z0-9_]*\]))\((?<parameters>.*)?\)(?:\sAs\s(?<reference>(((?<library>[a-zA-Z][a-zA-Z0-9_]*))\.)?(?<identifier>([a-zA-Z][a-zA-Z0-9_]*)|\[[a-zA-Z0-9_]*\]))(?<array>\((?<size>(([0-9]+)\,?\s?)*|([0-9]+\sTo\s[0-9]+\,?\s?)+)\))?)?";
}
}
Отчасти это избыток и будет соответствовать нелегальным синтаксисам массивов (в контексте сигнатуры процедуры), но это не мое беспокойство прямо сейчас.
Проблема в том, что эта часть:
\((?<parameters>.*)?\)
ломается, когда функция (или свойство getter) возвращает массив, потому что тогда подпись будет выглядеть примерно так:
Public Function GetSomeArray() As Variant()
Или вот так:
Public Function GetSomeArray(ByVal foo As Integer) As Variant()
И это делает тип возвращаемой функции полностью запутанным, потому что группа захвата parameters
получит это:
ByVal foo As Integer) As Variant(
Я знаю, почему это происходит - потому что мое регулярное выражение принимает последнюю закрывающую фигуру, которая ограничивает группу захвата parameters
.
Есть ли способ исправить мое регулярное выражение, чтобы изменить это, не слишком сильно влияя на производительность?
Ловушка заключается в том, что это допустимая подпись:
Public Function DoSomething(foo As Integer, ParamArray bar()) As Variant()
У меня есть другое отдельное регулярное выражение для обработки отдельных параметров, и это будет отлично работать... если этот не запутался с типами возврата массива.
Это то, что я получаю:
Что мне нужно, это группа parameters
, которая не включает в себя часть ) As Variant(
, например, когда тип возвращаемого значения не является массивом: