如何匹配否定集中的序列

时间:2017-10-05 13:49:42

标签: regex regex-negation

考虑以下表达式:

((password|secret)(=|%3D%22))+([^&|\"|%22]*)

价值:

http://host?foo=bar&xml=%3C%3Fxml+id%3D%220abc987%22+password%3D%22secreT12aa5%22+binds%3D%222%22

xml参数包含编码值<?xml id="0abc987" password="secreT12aa5" binds="2"

我想要达到的是匹配password="secreT12aa5",然后将其替换为例如password="****"

这个问题是给定的正则表达式匹配,只匹配最多2的字符串序列,这是因为否定集%22中的值。百分号正在被忽略。

如何更改表达式以匹配 password%3D%22secreT12aa5 (整个密码值?)

表达式也应该与http://host?password=value匹配。目前的情况。

enter image description here

我想将此正则表达式也用于替换。并使用replaceAll()方法实际去除匹配的参数值。

因此,使用替换((password)(=|%3D%22))([^&|\\"]*)(%22)?的正则表达式$1[PROTECTED]$5会自动替换:

password=VALUE 
to => 
password=[PROTECTED]

password=VALUE&secret=VALUE 
to => 
password=[PROTECTED]&secret=[PROTECTED]

http://host?foo=bar&xml=%3C%3Fxml+id%3D%220abc987%22+password%3D%22secreT12345%22+binds%3D%222%22 
to => 
http://host?foo=bar&xml=%3C%3Fxml+id%3D%220abc987%22+password%3D%22[PROTECTED]%22+binds%3D%222%22

1 个答案:

答案 0 :(得分:2)

请注意[^&|\"|%22]是一个否定的字符类,它匹配除&|(是的,管道),"%2之外的所有字符。 password(?:="?|%3D%22)(?:(?!%22)[^&\"])*"? 因为在字符类中,所有字符都是单独处理的,而不是 sequence

您可以使用

password

请参阅regex demo

<强>详情

  • (?:="?|%3D%22) - 文字子字符串
  • = - "后跟可选的%3D%22(?:(?!%22)[^&\"])*
  • & - 除了"[^&\"]*)之外的任何字符,尽可能多地出现0个或多个{%22),但不是启动"? char序列(所谓的tempered greedy token)。
  • " - 可选的password(?:="?|%3D%22)[^&\"%]*(?:%(?!22)[^%&\"]*)*"?

您可以使用"unroll-the-loop" principle作为

重新编写模式
password(?:="?|%3D%22)[^&\"]*?(?:(?=%22)|\"|$)

请参阅another demo

另外,其他人更喜欢使用交替方法的懒惰模式+前瞻:

Private oTest                   As Class1
Private InitDone                As Boolean
Private Map1(0 To 63)           As Byte
Private Map2(0 To 127)          As Byte

#If VBA7 Then
  Public Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#Else
  Public Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#End If

Private Declare Sub CopyMemoryByref Lib "Kernel32.dll" & _
                    Alias "RtlMoveMemory" (ByRef dest As Integer, ByRef & _
                    source As Integer, ByVal numBytes As Integer)

Private Declare Function VarPtr Lib "vb40032.dll" & _
                         Alias "VarPtr" (lpObject As Integer) As Long

Public Function EncryptData(ByRef bytMessage() As Byte, ByRef bytPassword() As Byte) As Byte()
        Dim bytKey(31) As Byte
        Dim bytIn() As Byte
        Dim bytOut() As Byte
        Dim bytTemp(31) As Byte
        Dim lCount, lLength As Integer
        Dim lEncodedLength, lPosition As Integer
        Dim bytLen(3) As Byte

        If Not IsInitialized(bytMessage) Then Exit Function
        If Not IsInitialized(bytPassword) Then Exit Function

        For lCount = 0 To UBound(bytPassword)
            bytKey(lCount) = bytPassword(lCount) : If lCount = 31 Then Exit For
        Next lCount

        gentables()
        gkey(8, 8, bytKey)
        lLength = UBound(bytMessage) + 1 : lEncodedLength = lLength + 4

        If lEncodedLength Mod 32 <> 0 Then lEncodedLength = lEncodedLength + 32 - (lEncodedLength Mod 32)

        ReDim bytIn(lEncodedLength - 1) : ReDim bytOut(lEncodedLength - 1)

        Try
            CopyMemory(VarPtr(bytIn(0)), VarPtr(lLength), 4)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        For lCount = 0 To lEncodedLength - 1 Step 32
           CopyMemory(VarPtr(bytTemp(0)), VarPtr(bytIn(lCount)), 32)
           Encrypt(bytTemp)
           CopyMemory(VarPtr(bytOut(lCount)), VarPtr(bytTemp(0)), 32)
        Next lCount
End Function

请参阅another regex demo