3

I have one string like below

A:82% X 18% Y B:100% X C:82% X 18% Y AB:82% X 18% Y

Want to convert above string into below format (Required Format)

#A:82% X,18% Y #B:100% X #C:82% X,18% Y #AB:82% X,18% Y

I'm able to achieve this

#A:82% X 18% Y #B:100% X #C:82% X 18% Y #AB:82% X 18% Y

using this code

String inp = "A:82% X 18% Y B:100% X C:82% X 18% Y AB:82% X 18% Y";
String regex = "(\\b[A-Za-z]{1,}\\:\\b)";   
System.out.println(inp.replaceAll(regex, "#$1"));

But am not able to find a way where I could place commas the way I want mentioned in required format.

Is there any way I could select only words except "#word:", "Number%" and "spaces", so that in resultant I could select only Xs and Ys (X and Y is just an example, other word are also possible). Because once am able to select those words then I can replace them with "$1,"

Thanks

3
  • is the number of (Number% Word) always fixed to 2 ? Commented Feb 26, 2018 at 12:59
  • @NahuelFouilleul, No..! Commented Feb 26, 2018 at 14:21
  • ok, see last update Commented Feb 26, 2018 at 14:31

4 Answers 4

1

EDIT: updated after comment regex

(\d+%\s[A-Z]+)\s(?=\d+%\s[A-Z]+)

will match pattern (Number% Word) followed by (Number% Word), without consuming the second as it is a lookahead.

\1,

Java code:

String inp = "A:82% X 18% Y B:100% X C:82% X 18% Y AB:60% X 20% Y 20% ZZ";
String regex = "(\\b[A-Za-z]{1,}\\:\\b)";
String inp2 = inp.replaceAll(regex, "#$1");
String regex2 = "(\\d+%\\s[A-Z]+)\\s(?=\\d+%\\s[A-Z]+)";
System.out.println(inp2.replaceAll(regex2, "$1,"));

Try it online

Sign up to request clarification or add additional context in comments.

5 Comments

this answer seems great
@Nahuel, But if I use this string "A:82% X 18% Y B:100% X C:82% X 18% Y AB:60% X 20% Y 20% ZZ", I'm not able to get comma before "20% ZZ".
@Squeez, i let the old answer at the end, but i will remove to make more clear
@NahuelFouilleul, Its working now...! Can you please explain little more your second regex...?
lookahead (?= .. ) is a zero width assertion which ensures that pattern matches at current position without moving forward position in input.
0

This should give you the part between X and Y (if there is one) [^X]*% Y

Comments

0

Assuming you always have input in the form #word:number% label number% label ... you could try the following regex to match the spaces between labels and numbers: (?!<:)\s+(?=\d+%)

Short breakdown:

  • (?!<:) is a negative lookbehing meaning the match must not be preceded by a colon
  • \s+ is a sequence of one or more spaces which you want to match
  • (?=\d+%) is a positive lookahead meaning the match must be followed by number%

In your test input that would match the space after each X.

Comments

0
([a-zA-Z]+:)([0-9]{1,3}%) ([a-zA-Z]+)(?: ([0-9]{1,3}%) ([a-zA-Z]+))?

With substitution:

#$1 $2 $3, $4 $5

You would need to have an if statement to make sure capture group 4 has captured something. If it hasn't, then use substitution:

#$1 $2 $3

See the Demo

This regex should be language agnostic (no escape characters used)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.