2

I have a substring in a string with the following format:

ID Number: 4D:9B:C4

I am using the following regex to match it:

ID Number: [A-Z0-9]{2}(:[A-Z0-9]{2}){2}

What I want to do is capture instances of substrings matching this regex (or just the first instance), then capture the ID number itself inside, and finally replace colons in the ID Number with spaces, so the output will be:

4D 9B C4

I've been playing around with using capture groups in replace all, surrounding my desired capture in parentheses, like this ....

String idNum = idNum.replaceAll("ID Number: ([A-Z0-9]{2}(:[A-Z0-9]{2}){2})", "$1");

But I'm not sure where to go from here or even if I'm taking the right approach. Any suggestions would be greatly appreciated.

EDIT: Perhaps I didn't phrase this the best way in the description, so I'll illustrate by example. The initial string I'm capturing is a substring within a larger string like ...

We got some text up here
  ID Number: 4D:9B:C4
  And also some text down here

And I want the output previously stated.

user2150250
  • 4,155
  • 10
  • 31
  • 41

4 Answers4

3

Through regex and regex ony. The anchor \G matches at the position where the previous match ended.

String s = "ID Number: 4D:9B:C4";
System.out.println(s.replaceAll("(?:ID Number: ([A-Z0-9]{2})|(?<!^)\\G):?([A-Z0-9]{2})","$1 $2"));

Output:

4D 9B C4

Another example with many number of colon separated parts.

String s = "ID Number: 4D:9B:C4:B5:C6:D7:F8:K9";
System.out.println(s.replaceAll("(?:ID Number: ([A-Z0-9]{2})|(?<!^)\\G):?([A-Z0-9]{2})","$1 $2"));

Output:

4D 9B C4 B5 C6 D7 F8 K9

References:

Update:

String s = "We got some text up here\n" +
           "ID Number: 4D:9B:C4:D4:F4\n" +
           "And also some text down here";
System.out.println(s.replaceAll("(?s)(?:ID Number: ([A-Z0-9]{2})|(?<!^)\\G):?([A-Z0-9]{2})|.*?(?=ID Number:)|.+","$1 $2").trim());
Community
  • 1
  • 1
Avinash Raj
  • 160,498
  • 22
  • 182
  • 229
  • Thanks so much for your great answer. Could you please review my edits above and modify or expand your answer to fit the exact nature of my problem? – user2150250 Nov 07 '14 at 16:52
  • It seems to only be affecting the one line in question and still outputting the other lines. My output is like ... We got some text up here 4D 9B C4 And also some text down here – user2150250 Nov 07 '14 at 17:03
  • I can't seem to put hard returns or fancy formatting in the comment, but imagine in the output I stated in the previous comment that the spaces between "here 4D" and "C4 And" are actually hard returns – user2150250 Nov 07 '14 at 17:07
  • Nevermind, I had an error in my copy to my code. I am still getting a leading whitespace in my output though. How do we lop that off? – user2150250 Nov 07 '14 at 17:28
  • Use trim function to remove the leading spaces. – Avinash Raj Nov 07 '14 at 17:37
1

I suggest using capture groups to actually get what you're interested in. There's no reason not to be repetitive.

String idNum = idNum.replaceAll(
   "ID Number: ([A-Z0-9]{2}):([A-Z0-9]{2}):([A-Z0-9]{2})",
   "$1 $2 $3"
);
Robert
  • 2,435
  • 23
  • 24
0

You can use a lookahead. And since you will probably use this pattern more than once, create it as a static final variable:

private static final Pattern PATTERN = Pattern.compile(":(?=[A-Z0-9]{2})");

// ...

idNum = PATTERN.matcher(idNum).replaceAll(" ");
fge
  • 110,072
  • 26
  • 223
  • 312
0

Providing the String schema doesn't change too much, I'd go with

String str = "ID Number: 4D:9B:C4"
numbers = str.split(':')[1].split(':')

Then you might have to .trim() your elements of the array 'numbers'.

After you can go with concatenating numbers[0-2] with spaces inbetween.

Andreas Gnyp
  • 1,106
  • 1
  • 14
  • 21