Ваше регулярное выражение (?<!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: ...")