3

I have a pretty long string that looks something like

{abc:\"def\", ghi:\"jkl\"}

I want to convert this to a valid json string like

{\"abc\":\"def\", \"ghi\":\"jkl\"}

I started looking at the replaceAll(String regex, String replacement) method on the string object but i'm struggling to find the correct regex for it.

Can someone please help me with this.

3
  • 2
    An alternate way would be to parse it using a lenient parser, e.g. Gson has a setLenient() method. Then write it back as valid JSON. Commented Dec 31, 2016 at 4:15
  • which json dependency you are using ? better option is to generate it according to the right format , no matter it's client side or server side Commented Dec 31, 2016 at 4:36
  • You could try doing a replace by searching for a sequence of identifier characters followed by :, but that could defeat you if there are colons in any of the value strings. Other things that could defeat you are escaped quote marks inside one of the values. It might be possible to come up with a complex regex that handles everything, but in a case like this it's best to write your own lexer to process tokens in the input (like {, :, ,, identifiers, string literals) and work from that. Overly complex regexes are unreadable and prone to error anyway. Commented Dec 31, 2016 at 4:47

2 Answers 2

2

In this particular case the regex should look for a word that is proceeded with {, space, or , and not followed by "

String str = "{abc:\"def\", ghi:\"jkl\"}";
String regex = "(?:[{ ,])(\\w+)(?!\")";
System.out.println(str.replaceAll(regex, "\\\"$1\\\""));

DEMO and regex explanation

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

Comments

0

I have to make an assumption that the "key" and "value" consist of only "word characters" (\w) and there are no spaces in them.

Here is my program. Please also see the comments in-line:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexJson {

    public static void main(String[] args) {
        /*
         * Note that the input string, when expressed in a Java program, need escape
         * for backslash (\) and double quote (").  If you read directly
         * from a file then these escapes are not needed
         */
        String input = "{abc:\\\"def\\\", ghi:\\\"jkl\\\"}";

        // regex for one pair of key-value pair.  Eg: abc:\"edf\"
        String keyValueRegex = "(?<key>\\w+):(?<value>\\\\\\\"\\w+\\\\\\\")";
        // regex for a list of key-value pair, separated by a comma (,) and a space ( )
        String pairsRegex    = "(?<pairs>(,*\\s*"+keyValueRegex+")+)";
        // regex include the open and closing braces ({})
        String regex         = "\\{"+pairsRegex+"\\}";

        StringBuilder sb = new StringBuilder();

        sb.append("{");
        Pattern p1 = Pattern.compile(regex);
        Matcher m1 = p1.matcher(input);
        while (m1.find()) {
            String pairs = m1.group("pairs");
            Pattern p2 = Pattern.compile(keyValueRegex);
            Matcher m2 = p2.matcher(pairs);
            String comma = "";      // first time special
            while (m2.find()) {
                String key      = m2.group("key");
                String value    = m2.group("value");
                sb.append(String.format(comma + "\\\"%s\\\":%s", key, value));
                comma = ", ";       // second time and onwards
            }
        }
        sb.append("}");

        System.out.println("input is: " + input);
        System.out.println(sb.toString());
    }

}

The print out of this program is:

input is: {abc:\"def\", ghi:\"jkl\"}
{\"abc\":\"def\", \"ghi\":\"jkl\"}

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.