如何匹配否定集中的序列

How to match sequence in a negate set

考虑以下表达式:

((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。目前是哪个。

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

Soe 正则表达式 ((password)(=|%3D%22))([^&|\"]*)(%22)? 替换 [PROTECTED] 自动替换:

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

请注意,[^&|\"|%22] 是一个取反字符 class,它匹配任何字符,但 &|(是的,管道)、"%2 因为在字符 class 内部,所有字符都被单独处理,而不是 序列 .

您可以使用

password(?:="?|%3D%22)(?:(?!%22)[^&\"])*"?

regex demo

详情

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

您可以使用 "unroll-the-loop" principle 重写模式,如

password(?:="?|%3D%22)[^&\"%]*(?:%(?!22)[^%&\"]*)*"?

参见 another demo

此外,其他人更喜欢惰性模式 + 交替方法的前瞻:

password(?:="?|%3D%22)[^&\"]*?(?:(?=%22)|\"|$)

还没看another regex demo.