Ваше регулярное выражение (?<!Sub).*\(.*\)
, разобрали:
(?<! # negative look-behind
Sub # the string "Sub " must not occur before the current position
) # end negative look-behind
.* # anything ~ matches up to the end of the string!
\( # a literal "(" ~ causes the regex to backtrack to the last "("
.* # anything ~ matches up to the end of the string again!
\) # a literal ")" ~ causes the regex to backtrack to the last ")"
Так, с тестовой строки:
Sub ChangeAreaTD()
- Взгляд-за выполняется сразу (справа в положении 0).
.*
отправляется в конец строки после этого.
- Из-за этого
.*
внешний вид никогда не имеет значения.
Вы, вероятно, думаете о
(?<!Sub .*)\(.*\)
, но это очень маловероятно, что переменная длина Двойник за поддерживаются вашими регулярными выражения.
Так что я хотел бы сделать это (с переменной длиной упреждающая широко поддерживается):
^(?!.*\bSub\b)[^(]+\(([^)]+)\)
, что переводится как:
^ # At the start of the string,
(?! # do a negative look-ahead:
.* # anything
\b # a word boundary
Sub # the string "Sub"
\b # another word bounday
) # end negative look-ahead. If not found,
[^(]+ # match anything except an opening paren ~ to prevent backtracking
\( # match a literal "("
( # match group 1
[^)]+ # match anything up to a closing paren ~ to prevent backtracking
) # end match group 1
\) # match a literal ")".
, а затем пойти на содержание матча группа 1.
Однако, регулярное выражение, как правило, плохо подходит для анализа кода. Это верно для HTML так же, как и для кода VB. Вы получите неправильные совпадения даже с улучшенным регулярным выражением. Например, из-за вложенных парнеров:
MsgBox ("The total run time to fix all fields (AREA, TD) is: ...")
О, я понимаю, почему это не удается сейчас. Не могли бы вы порекомендовать другой способ для анализа кода? Я пошел с регулярным выражением, потому что одна из вещей, которые я заметил о VBA, заключается в том, что каждое определение всегда имеет только одну строку. В отличие от C#, где вы можете, например, иметь (), а затем скобку в следующей строке, VBA всегда держит все в одной строке. –
@Tiago: Это не совсем так. Вы можете вставить подчеркивание в конце строки, и это считается продолжением строки. Вы можете разделить две логические строки кода с двоеточием ('Dim x: x = 10'). Для разбора языков всегда используйте синтаксический анализатор. Не уверен, есть ли синтаксический анализатор, который вы можете использовать для разбора кода VB, но его не должно быть сложно записать. Тем не менее, это материал для отдельного вопроса. – Tomalak
Хорошее горе. Я не знал о знаке подчеркивания, или, вернее, знал об этом с VB .NET, я просто не думал, что это применимо и к VBA. Я просто проверил, и это так, как и двоеточие. Я думаю, что я просто закончу замену двоеточий '\ r \ n' и удалю все экземпляры '_ \ r \ n', поскольку подчеркивание должно быть последним символом в строке для его работы. Я пробовал искать парсер для VBA и, похоже, не один, плюс у меня есть около трех месяцев, чтобы придумать что-то, что создает абстрактное синтаксическое дерево из кода VBA, а затем что-то другое, которое генерирует C# из этого АСТ. –