Узор в @Jeff Wurz's comment (^\'[^\r\n]+$|''[^\r\n]+$
), даже не соответствует любой ваших тестовых образцов, и связанный вопрос не имеет смысла, регулярное выражение там будет соответствовать только , что конкретный комментарий в вопросе Ор в, а не " синтаксис комментария VBA ".
Регулярное выражение, которое вы придумали, работает даже лучше, чем у меня, когда я отказался от подхода с регулярным выражением.
Молодцы!
Проблема в том, что вы не можете анализировать комментарии VBA с помощью регулярного выражения.
В Lexers vs Parsers, @SasQ's answer делает хорошую работу в объяснении уровней грамматики Хомского:
Уровень 3: Регулярные грамматики
Они используют регулярные выражения, то есть, они могут состоять только из символы алфавита (a, b), их конкатенации (ab, aba, bbb etd.) или альтернативы (например, a | b). Они могут быть реализованы как конечное состояние автоматов (FSA), таких как NFA (недетерминированный конечный автомат) или лучше DFA (детерминированный конечный автомат). Регулярные грамматики не могут обрабатывать с вложенным синтаксисом, например. правильные вложенные/совпадающие скобки (()() (()())), вложенные теги HTML/BBcode, вложенные блоки и т. д. Это потому, что автоматы состояний, с которыми приходится иметь дело, должны иметь бесконечное число состояний для бесконечной обработки многие уровни гнездования.
Уровень 2: контекстно-свободных грамматики
Они могут иметь вложенные, рекурсивные, самоподобные ветви в их синтаксисе дерев, поэтому они могут работать с вложенными структурами хорошо. Они могут быть реализованы как государственный автомат со стеклом. Этот стек используется для представляет уровень вложенности синтаксиса. На практике они равны , которые обычно выполняются как парсер с наименьшим, рекурсивным спусками, который использует стек вызовов процедуры обработки вызовов для отслеживания уровня вложенности и использует рекурсивно называемые процедуры/функции для каждого нетерминального символа в своем синтаксисе ,Но они не могут обрабатывать контекстно-зависимый синтаксис . Например. когда у вас есть выражение х + 3 и в одном контексте, это х может быть имя переменной, а в другом контексте это может быть имя функции и т.д.
Уровень 1: контекстно-зависимых грамматик
регулярных выражения просто не являются подходящим инструментом для решения этой проблемы, потому что всякий раз, когда есть более одного цитаты (/ апостроф), или когда двойные кавычки вовлечены, вы должны выяснить, является ли левши большинство апострофов в строке кода находятся внутри двойных кавычек, а если это так, то вам нужно сопоставить двойные кавычки и найти самый левый апостроф после закрытия d котировка ouble - фактически, самый левый апостроф, который не является частью строкового литерала, является вашим комментарием.
Я понимаю, что VBA комментарий синтаксис является контекстно-зависимая грамматика (уровень 1), так как апостроф только ваш маркер, если он не является частью строкового литерала, и выяснить апостроф является ли частью строковый литерал, проще всего, чтобы перейти к вашей строке слева направо и переключить флаг IsInsideQuote
, поскольку вы сталкиваетесь с двойными кавычками ... но только если они не экранированы (удваиваются). На самом деле вы даже не проверяете, есть ли апостроф внутри строки litereal: вы просто продолжаете идти до тех пор, пока открытые кавычки не будут закрыты, и только когда флаг «в кавычках» равен False
, вы нашли маркер комментария, если столкнулись с одним цитаты.
Удачи вам!
Вот тест вам не хватает:
s = "abc'def ""xyz""'nutz!" 'string with apostrophes and escaped double quotes
Если вы не заботитесь о захвате строковых литералов, вы можете просто игнорировать сбежавшие двойные кавычки и см 3 строковых литералов здесь: "abc'def "
, "xyz"
и "'nutz!"
.
Это C# код выхода 'string with apostrophes and escaped double quotes
(все в струне двойные кавычки экранируются с помощью обратной косой черты в коде), и работает со всеми тестовыми строками, которые я дал его:
static void Main(string[] args)
{
var instruction = "s = \"abc'def \"\"xyz\"\"'nutz!\" 'string with apostrophes and escaped double quotes";
// var instruction = "s = \"the cat's hat\" ' quote within string -- works";
// var instruction = "dim s as string ' string should be set to \"ten\"";
int? commentStart = null;
var isInsideQuotes = false;
for (var i = 0; i < instruction.Length; i++)
{
if (instruction[i] == '"')
{
isInsideQuotes = !isInsideQuotes;
}
if (!isInsideQuotes && instruction[i] == '\'')
{
commentStart = i;
break;
}
}
if (commentStart.HasValue)
{
Console.WriteLine(instruction.Substring(commentStart.Value));
}
Console.ReadLine();
}
Затем, если вы хотите записать все легальные комментарии, вам необходимо обработать ключевое слово Rem
и рассмотреть продолжение линии:
Rem this is a legal comment
' this _
is also _
a legal comment
Другими словами, \r\n
сам по себе недостаточно, чтобы правильно идентифицировать все токены конца.
Правильный лексер + парсер, кажется, единственный способ захватить все комментарии.
[Повторить вопрос?] [1] [1]: http://stackoverflow.com/questions/311888/regular-expression-to-get-comments-in-vb-net-source -код Попробуйте '^ \ '[^ \ r \ n] + $ |' '[^ \ r \ n] + $' –