Java正则表达式:替换字符串(URL)的部分内容

3
我想只替换一个字符串中的数字部分。大多数情况下,它是完整URL或URL的一部分,但它也可能仅是普通字符串。
- /users/12345 变成 /users/XXXXX - /users/234567/summary 变成 /users/XXXXXX/summary - /api/v1/summary/5678 变成 /api/v1/summary/XXXX - http://example.com/api/v1/summary/5678/single 变成 http://example.com/api/v1/summary/XXXX/single 请注意,我没有更改 /api/v1 中的 1。
到目前为止,我只发现以下代码可以在大多数情况下工作:
input.replaceAll("/[\\d]+$", "/XXXXX").replaceAll("/[\\d]+/", "/XXXXX/");

但是这种方法存在两个问题:

  • 替换后的长度与原始字符串长度不匹配。
  • 替换字符是硬编码的。

有更好的解决方法吗?

3个回答

3
在Java中,你可以使用以下方法:
str = str.replaceAll("(/|(?!^)\\G)\\d(?=\\d*(?:/|$))", "$1X");

正则表达式演示

正则表达式细节:

  • \G 断言匹配的位置在前一个匹配的结尾或字符串的开始位置(对于第一次匹配)。
  • (/|(?!^)\\G):在捕获组 #1 中匹配/或前一个匹配的结尾(但不在起始位置)。
  • \\d:匹配一个数字。
  • (?=\\d*(?:/|$)):确保数字后面跟着/或结束符。
  • 替换:$1X:用捕获组 #1 后跟 X 替换它。

2
非常好,但是你需要在斜杠或字符串结尾处关闭,以避免匹配数字后面跟着非数字字符的情况。 - oriberu
当然,(/|(?!^)\G)\d(?=\d*(?:/|$)) 可以用来确保这一点,但是这种情况并没有在 OP 的要求中特别提到。 - anubhava
也许我误解了原帖的第一句话:“我想仅替换字符串中的数字部分。” - oriberu

0

虽然我不是一个Java专家,但这个想法应该是通用的。只需捕获一个/、数字和可选的/,计算第二组的长度并将其放回即可。

所以

(/)(\d+)(/?)

变成

$1XYZ$3

请参考regex101.com上的演示这个答案,获取类似于PythonPHP的lambda等效代码。


谢谢Jan的回复。但是Java正则表达式与其他语言有些不同,不能真正地进行1-1映射。@anubhava提供了另一个可行的答案。 - Garbage

0
首先,您需要像这样的东西:
String new_s1 = s3.replaceAll("(\\/)(\\d)+(\\/)?", "$1XXXXX$3");

1
谢谢回复。然而,这并没有解决问题中提到的任何两个问题。请参考@anubhava的答案,它可以完美地解决这些问题。 - Garbage
1
的确,他提供了最佳答案。向他致敬! - Catalina Chircu

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