【问题标题】:Regex to replace word except in comments正则表达式替换评论中的单词
【发布时间】:2020-08-05 05:45:49
【问题描述】:

如何修改我的正则表达式,使其忽略模式中不支持后视的语言中的 cmets?

我的正则表达式模式是:

\b{Word}\b(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)
  • \b{Word}\b : 整个单词,{word} 被迭代替换为词汇表
  • (?=([^""\](\.|""([^""\]\.)[^""\]" "))[^""]$) :不要替换引号内的任何内容

我的目标是对变量和单词进行 lint,以便它们始终具有相同的大小写。但是,我不想在评论中删除任何文字。 (IDE很烂,没有其他选择)

这种语言的注释以撇号为前缀。示例代码如下

' This is a comment
This = "Is not" ' but this is 
' This is a comment, what is it's value?
Object.value = 1234 ' Set value
value = 123

基本上我希望 linter 采用上面的代码并说“值”这个词将其更新为:

' This is a comment
This = "Is not" ' but this is 
' This is a comment, what is it's value?
Object.Value = 1234 ' Set value
Value = 123

因此,所有基于代码的“值”都会更新,但不会触及双引号或注释中的任何内容或其他单词的一部分,例如 value added。

我尝试了几种解决方案,但都无法正常工作。

  • ['.*] : 前面没有撇号
  • (?
  • (?

任何人都知道如何改变我的模式,这样我就不会编辑注释变量

VBA


Sub TestSO()
    Dim Code As String
    Dim Expected As String
    Dim Actual  As String
    Dim Words   As Variant
    Code = "item = object.value ' Put item in value" & vbNewLine & _
              "some.item <> some.otheritem" & vbNewLine & _
              "' This is a comment, what is it's value?" & vbNewLine & _
              "Object.value = 1234 ' Set value" & vbNewLine & _
              "value = 123" & vbNewLine

    Expected = "Item = object.Value ' Put item in value" & vbNewLine & _
              "some.Item <> some.otheritem" & vbNewLine & _
              "' This is a comment, what is it's value?" & vbNewLine & _
              "Object.Value = 1234 ' Set value" & vbNewLine & _
              "Value = 123" & vbNewLine
    
    Words = Array("Item", "Value")
    Actual = SOLint(Words, Code)
    Debug.Print Actual = Expected
    Debug.Print "CODE: " & vbNewLine & Code
    Debug.Print "Actual: " & vbNewLine & Actual
    Debug.Print "Expected: " & vbNewLine & Expected
    
End Sub
Public Function SOLint(ByVal Words As Variant, ByVal FileContents As String) As String
    Const NotInQuotes  As String = "(?=([^""\\]*(\\.|""([^""\\]*\\.)*[^""\\]*""))*[^""]*$)"
    Dim RegExp      As Object
    Dim Regex    As String
    Dim Index       As Variant
    
    
    Set RegExp = CreateObject("VBScript.RegExp")

    With RegExp
        .Global = True
        .IgnoreCase = True
    End With
    
    For Each Index In Words
        Regex = "[('*)]\b" & Index & "\b" & NotInQuotes
        RegExp.Pattern = Regex
    
        FileContents = RegExp.Replace(FileContents, Index)
    Next Index
    
    SOLint = FileContents
End Function

【问题讨论】:

  • ` (?:\".*\")|(?:'.*)|(value) ` - 它在“”和“”之外捕获“值”字符串。这是你要找的吗? regex101.com/r/mD9JeR/4
  • 这似乎不太正确,当我通过替换函数传递它时,我松开了 cmets。理想情况下,我想用正则表达式替换现有的值。但它确实看起来更近了。我会尝试使用它,看看我是否可以让它做我需要的事情。
  • 您尝试使用哪种语言?可以贴一下代码吗?
  • regex101.com/r/mD9JeR/7 - 我又改了。这个可以吗 ?您可以检查替换部分以查看预期的输出。
  • 我认为唯一的变化是 ((?:\".*\")|(?:'.*))|\b(v)(alue)\b 添加 \b这样增值就不会被捡起来。这似乎行得通。我还没有完全测试它,你能解释一下替换吗,我不确定我理解分组是如何处理那个的。这个解决方案意味着我需要在单词上做一些工作,但似乎就是这样。我会尽快添加代码更新

标签: regex


【解决方案1】:

如上面的 cmets 所述:

((?:\".*\")|(?:'.*))|\b(v)(alue)\b

此正则表达式的 3 个部分交替使用。

  1. 双引号内文本的非捕获组,因为我们不需要它。

  2. 以单引号开头的文本的非捕获组

  3. 最后,字符串“value”被分成两部分 (v) 和 (value),因为在替换时我们可以使用 \U($2) 将 v 转换为 V 并保持原样 \E$3 其中 \U - 转换大写和 \E - 关闭大小写。

  4. \b \b - 单词边界用于避免任何不属于设置值的独立文本。

https://regex101.com/r/mD9JeR/8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 2012-02-02
    • 2020-01-06
    • 1970-01-01
    • 2011-09-23
    • 2015-09-03
    • 2019-07-29
    相关资源
    最近更新 更多