如何在Java中用“XXXXX”替换字符串值?

4
我想要用"XXXX"替换特定的字符串值,问题在于模式非常动态,输入数据中没有固定的模式。
我的输入数据如下:

https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme

我需要用"XXXX"替换userId和password的值。
我的输出应该是 -

https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXX&password=XXXX&reme

这只是一个例子。还有其他情况仅存在userId和password -

userId=12345678&password=stackoverflow&rememberID=

我正在使用Java中的正则表达式来实现上述操作,但尚未成功。感谢您的任何指导。
[&]([^\\/?&;]{0,})(userId=|password=)=[^&;]+|((?<=\\/)|(?<=\\?)|(?<=;))([^\\/?&;]{0,})(userId=|password=)=[^&]+|(?<=\\?)(userId=|password=)=[^&]+|(userId=|password=)=[^&]+

PS: 我不是正则表达式的专家。此外,如果有其他实现这个目标的方法,请告诉我。


9
发送密码时,如果使用 GET 方法,应该被解雇。另外,没有必要使用正则表达式来处理这些内容,只需使用常见的字符串操作,例如 indexOf 和 replace。 - maio290
5个回答

4
这可能包括两种情况。

String maskUserNameAndPassword(String input) {
    return input.replaceAll("(userId|password)=[^&]+", "$1=XXXXX");
}

String inputUrl1 = 
    "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";

String inputUrl2 = 
    "userId=12345678&password=stackoverflow&rememberID=";

String input = "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";

String maskedUrl1 = maskUserNameAndPassword(inputUrl1);
System.out.println("Mask url1: " + maskUserNameAndPassword(inputUrl1));

String maskedUrl2 = maskUserNameAndPassword(inputUrl1);
System.out.println("Mask url2: " + maskUserNameAndPassword(inputUrl2));

以上将产生以下结果:
Mask url1: https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXXX&password=XXXXX&reme
Mask url2: userId=XXXXX&password=XXXXX&rememberID=

如果密码或用户ID值包含一些URL转义文本怎么办? - David Amar
然后,您首先应用URL解码,然后掩盖userId和password。 java.net.URLDecoder.decode(url, StandardCharsets.UTF_8); - wpnpeiris
然后呢?之后您重新进行URL编码以保留其他值不变吗?将\w更改为更准确的内容是否更简单?另外,如果解码的密码包含@或$等字符,该怎么办?修复\w一举两得。 - David Amar
是的,确实最好改进 \w 以支持特殊字符。 - wpnpeiris
在这里发现了@TeWu提出的建议。 它可能涵盖比\w更多的情况。 但是假设userIdpassword内不允许使用&字符。 - wpnpeiris

3

这也将替换类似于authorizeduserId=...或类似的字符串为password。 - David Amar
replaceAll("([?&])(userId|password)=[^&]+", "$1$2=XXXX")可以解决这个问题,但我不确定在这种情况下是否有必要这样做;特别是当您注意到authorizeduserId可能会变成authorizedUserId(请注意大写的U);即使存在authorizeduserId,它也可能是您想掩盖的内容。无论如何,您发现了这个问题,感谢提醒。 - TeWu

3
我更倾向于使用URL解析器而不是正则表达式。下面的示例使用Java中可用的标准URL类,但第三方库可以做得更好。
Function<Map.Entry<String, String>, Map.Entry<String, String>> maskUserPasswordEntries = e ->
        (e.getKey().equals("userId") || e.getKey().equals("password")) ? Map.entry(e.getKey(), "XXXX") : e;
Function<List<String>, Map.Entry<String, String>> transformParamsToMap = p ->
        Map.entry(p.get(0), p.size() == 1 ? "" : p.get(p.size() - 1));

URL url = new URL("https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme");
String maskedQuery = Stream.of(url.getQuery().split("&"))
        .map(s -> List.of(s.split("=")))
        .map(transformParamsToMap)
        .map(maskUserPasswordEntries).map(e -> e.getKey() + "=" + e.getValue())
        .collect(Collectors.joining("&"));
System.out.println(url.getProtocol() + "://" + url.getAuthority() + url.getPath() + "?" + maskedQuery);

输出:

https://internetbanking.abc.co.uk/personal/logon/login/?userId=XXXX&password=XXXX&reme=

2

使用:

(?<=(\?|&))(userId|password)=(.*?)(?=(&|$))
  • (?<=(\?|&)) 用于匹配前面是 ? 或者 & 的位置(但不包括匹配结果本身)
  • (userId|password)= 匹配 userId 或者 password, 然后匹配 =
  • (.*?) 匹配任何字符,直到下一步指令无法执行
  • (?=(&|$)) 用于匹配下一个字符是 & 或字符串结尾的位置(但不包括匹配结果本身)

然后,将其替换为 $2=xxxxx (保留 userIdpassword) 并选择 replaceAll


2

只需使用String类的replace / replaceAll方法,它们支持Charset和正则表达式。

String url = "https://internetbanking.abc.co.uk/personal/logon/login/?userId=Templ3108&password=Got1&reme";

url = url.replaceAll("(userId=.+?&)", "userId=XXXX&");
url = url.replaceAll("(password=.+?&)", "password=XXXX&");

System.out.println(url);

我也不是正则表达式专家,但如果你觉得有用的话,我通常使用这个网站测试我的表达式并作为在线备忘录: https://regexr.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接