-1

I have got a string in below format:

String test = '11, -22|32.45, 34|32, 41|32, 12.12';

I am trying to convert it into below format:

{"a":11,"b":-22|"a":32.45,"b":34|"a":32,"b":41| "a":32,"b":12.12}

I tried using the logic by split() and then using join but couldn't achieve it and logic fails.

List<String> numVar = test.split('\\|');
String finalStr = '{';
for(String st : numVar){
finalStr += 'a:'+st.split(',')[0]+',';
finalStr += 'b:'+st.split(',')[1];
    //trying to add join by | logic here.
}
finalStr += '}';```
5
  • Why that format? Do you mean actual JSON? Or exactly as specified?
    – sfdcfox
    Commented Oct 19, 2022 at 22:14
  • You should also edit your question to show us what you've tried so far. Even if it's wrong or runs into errors, it'll help people guide you through errors (conceptual, semantic, syntactic, etc...)
    – Derek F
    Commented Oct 19, 2022 at 22:34
  • @sfdcfox Yes. the exact format. Basically a string is being converted into another JSON string. Commented Oct 19, 2022 at 22:58
  • Thanks @DerekF I have added the same in question. Commented Oct 19, 2022 at 23:11
  • Well... that's not JSON, but if that's what you're insisting on...
    – sfdcfox
    Commented Oct 19, 2022 at 23:20

2 Answers 2

3

You can use String.replaceAll to match patterns

String testString = '11, -22|32.45, 34|32, 41|32, 12.12';
String resultString = '{'+testString.replaceAll('(-?[\\d+\\.]+), ?(-?[\\d+\\.]+)','"a":$1,"b":$2')+'}';
System.debug(resultString); // {"a":11,"b":-22|"a":32.45,"b":34|"a":32,"b":41|"a":32,"b":12.12}

This avoids the need to split and/or use any loops at all.


Edit:

For the regular expression, we have the following concepts:

  • In Apex, a literal \ must be escaped, because Apex uses this as an escape character, too.
  • To match a literal \ in Regex, we need to escape it: \\ (not used here).
  • So, to match a literal \ in Regex/Apex, we need to write \\\\ (not used here).
  • [...] specifies a character set, for which we use [0123456789\.]+, which is also simply [\d\.].
  • ? means "match zero or once".
  • + means "match at least once".
  • (...) is a "capture group", which we can later reference as $1, $2, etc for each group from left to right.

For a more complete regular expression tutorial, consider a site like regex101.com, regular-expressions.info, etc.

2
  • Thanks @sfdcfox That helped. I would highly appreciate some regex lessons I can take up as a beginner. I knew this can be fixed by regex but gave up as I couldn't frame the regex. Thanks in advance. Commented Oct 19, 2022 at 23:39
  • @user15754268 Added a crash course. You should definitely check out additional resources, there's a lot out there.
    – sfdcfox
    Commented Oct 19, 2022 at 23:52
2

Note that the first split on the pipe (|) is going to give you a list of strings like
['11, -22', '32.45, 34', '32, 41', '32, 12.12']

So to process this further, you'll either need to split() again, or just use replace() with a simple regex.

ex.

// Doesn't hurt to do this outside of the loop, but it also doesn't help
//List<String> parts = testStr.split('\\|');

List<String> processed = new List<String>();
for(String part :testStr.split('\\|')){
    system.debug(part); // should print things like '32.45, 34'

    // Using some simple regex with capturing groups to get the a/b part of the format
    // The $1 and $2 get replaced with the first and second capturing groups
    //   (the stuff contained inside the `()`) respectively
    // [0-9.-]+ covers integer strings, decimal strings, and negative numbers
    processed.add(part.replace('([0-9\\-.]+), ([0-9\\-.]+)', '"a":$1,"b":$2));
}

The result of that should be ['"a":11,"b":-22', "a":32.45,"b":34', '"a":32,"b":41','"a":32,"b":12.12']. The square braces just indicate that it's part of a list.

From there, it should be a simple String.join() to get the final output

1
  • Or, you know, String.replaceAll.😅
    – sfdcfox
    Commented Oct 19, 2022 at 23:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .