3

I want to replace only numeric section of a string. Most of the cases it's either full URL or part of URL, but it can be just a normal string as well.

  • /users/12345 becomes /users/XXXXX
  • /users/234567/summary becomes /users/XXXXXX/summary
  • /api/v1/summary/5678 becomes /api/v1/summary/XXXX
  • http://example.com/api/v1/summary/5678/single becomes http://example.com/api/v1/summary/XXXX/single

Notice that I am not replacing 1 from /api/v1

So far, I have only following which seem to work in most of the cases:

input.replaceAll("/[\\d]+$", "/XXXXX").replaceAll("/[\\d]+/", "/XXXXX/");

But this has 2 problems:

  • The replacement size doesn't match with the original string length.
  • The replacement character is hardcoded.

Is there a better way to do this?

Garbage
  • 1,490
  • 11
  • 23

3 Answers3

3

In Java you can use:

str = str.replaceAll("(/|(?!^)\\G)\\d(?=\\d*(?:/|$))", "$1X");

RegEx Demo

RegEx Details:

  • \G asserts position at the end of the previous match or the start of the string for the first match.
  • (/|(?!^)\\G): Match / or end of the previous match (but not at start) in capture group #1
  • \\d: Match a digit
  • (?=\\d*(?:/|$)): Ensure that digits are followed by a / or end.
  • Replacement: $1X: replace it with capture group #1 followed by X
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 2
    Very nice, but you'll need to close on either a slash or the end of string in order to avoid matching numbers followed by non-numeric characters. – oriberu Mar 16 '20 at 19:02
  • Sure, `(/|(?!^)\G)\d(?=\d*(?:/|$))` can be used to ensure that but this case wasn't specifically mentioned in OP's requirements. – anubhava Mar 16 '20 at 19:07
  • Maybe I misinterpreted the OP's first sentence: "I want to replace only numeric section of a string." – oriberu Mar 16 '20 at 19:08
0

Not a Java guy here but the idea should be transferrable. Just capture a /, digits and / optionally, count the length of the second group and but it back again.

So

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

becomes

$1XYZ$3

See a demo on regex101.com and this answer for a lambda equivalent to e.g. Python or PHP.

Jan
  • 42,290
  • 8
  • 54
  • 79
  • Thanks Jan for the reply. But Java regex are little different than other languages are not really mapped 1-1. There is another answer by @anubhava which works. – Garbage Mar 16 '20 at 19:44
0

First of all you need something like this :

String new_s1 = s3.replaceAll("(\\/)(\\d)+(\\/)?", "$1XXXXX$3");
Catalina Chircu
  • 1,506
  • 2
  • 8
  • 19