【问题标题】:Finding VBA Comments using RegEx使用 RegEx 查找 VBA 注释
【发布时间】:2017-05-27 16:32:39
【问题描述】:

我正在尝试使用正则表达式查找所有 VBA cmets。我有一些最有效的方法,但也有一些我无法弄清楚的例外情况。

我正在使用的表达式:

'(?!.*").*

获取我们的测试代码:

Working - This is a test 'This should be captured
Working - "this is a test" 'This should be captured
Not Working - "this is a test" 'This should be "captured"
Not Working - This is a test 'This should be "captured"
Working - "this is a test 'this should not capture'" 'this should capture
Working - "this isn't a test" 'this should capture

这是 RegExr 中此示例的链接:http://regexr.com/3f24h

由于某些原因,第三个和第四个示例没有捕获。问题似乎在于 cmets 中有一个字符串值,我不知道如何解决它。

有什么建议吗?

【问题讨论】:

  • 第三个包含双引号和' 之后的子字符串,由于(?!.*") 前瞻条件,不能有双引号。
  • 试试'(?!\*\*)(?!\* )[^']*$regexp.Multiline=True
  • 在这里试一试regex101.com
  • 这行得通,但在最后一行变得很奇怪,它变得流氓并抓住了一切。 regexr.com/3f24h
  • 没错。实际上,上下文可能要复杂得多,通常需要一个解析器来获取这些 cmets。

标签: regex vba comments


【解决方案1】:

这应该可行:

("[^"]+"\s)?'.+

在这里测试:https://regex101.com/r/dd60QS/1

【讨论】:

    【解决方案2】:

    可能是这样的

    ^(?:[^"'\n]*("(?:[^"\n]|"")*"))*[^"]*'(.*)$
    

    它处理多个带引号的字符串,以及带引号(双)" 的字符串(我相信这是 VBA 的方式)。

    (我保证它在某些情况下会失败,但可能会在大多数情况下工作;)

    Check it out here at regex101.

    编辑

    添加了一些共产国际的例子并调整了正则表达式。它仍然无法处理 括号内的标识符(我什至不知道这意味着什么:S 请参阅最后一行)。但它现在可以处理他的连续线路 cmets。

    ^(?:[^"'\n]*(?:"(?:[^"\n]|"")*"))*[^']*('(?:_\n|.)*)
    

    Check it out here at regex101.

    【讨论】:

    • 我建议进行一个小调整 - 续行运算符仅在其前面有一个空格时才被视为行续行:\s_\n。我在顶部代码块的底部添加了一个示例(语法高亮的示例...)。
    • 赞成,干得好——虽然我不想调试那个正则表达式模式!调试actual parser grammar 似乎要简单得多;-)
    • “只是在做我的主人竞标”;)
    【解决方案3】:

    您无法使用正则表达式 - 句点在 VBA 代码中找到所有 cmets(更不用说字符串文字了)。相信我,我在Rubberduck 的 Smart Indenter 模块上进行了尝试(以防不够明确 - 完全公开,我是贡献者)。您需要实际解析代码。您将遇到的第一个问题是续行:

    'Comment with a line _
    continuation
    
    Debug.Print 'End of line comment _
    with line continuation.
    
    Debug.Print 'Multiple line continuation operators _ _
    still work.
    
    Debug.Print 'This is actually *not* a line continuation_
    Debug.Print 42
    

    这使得很难识别字符串文字,尤其是您使用逐行处理:

    Debug.Print 42 'The next line... _
    "...is not a string literal"
    

    您还必须处理旧的Rem 注释语法...

    Rem old school comment
    

    ...也支持换行:

    Rem old school comment with line _
    continuation.
    

    你可能会想“这还不算太糟糕,雷姆必须开始一条线”。如果你是,你忘了语句分隔符(:)......

    Debug.Print 42: Rem statement separator comment.
    

    ...或其邪恶的双胞胎语句分隔符与续行相结合:

    Debug.Print 42: Rem this can be _
    continued too.
    

    您讨论了一些关于排序字符串文字和 cmets 的问题...

    Debug.Print "Unmatched double quotes." 'Comment"
    Debug.Print "Interleaved single 'n double quotes." 'Comment"
    

    ...但是像这个野兽这样的括号标识符呢(@ThunderFrame 提供)?

    'No comments or strings in the line below.
    Debug.Print [Evil:""Comment"'here] 
    

    请注意,SO 使用的语法荧光笔甚至无法捕捉到所有这些奇怪的极端情况。

    【讨论】:

    • VBE 语法高亮如何捕捉所有这些?
    • @Vityata - VBE 语法高亮不使用正则表达式 - 它解析代码。
    • 写完评论后我立即想到的事情。顺便说一句,在您使用Evil 的最后一个示例中,您是否缺少"
    • @Vityata - 括号内的任何标识符都被视为标识符本身的一部分 - 字符本身的上下文在括号内切换。
    • @Vityata - 在 Excel 中,它被视为一个表达式(因此您可以将它用于命名范围)。它也可以用作 COM 成员调用 - 即ws.[_CheckSpelling]。我怀疑您是否会在 COM 中遇到任何成员名称包含引号的东西,但它可能是可行的,因为对象可以随意实现 GetIDsOfNames
    猜你喜欢
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多