firestreak
firestreak

Reputation: 447

Trying to split a string into 3 parts with Regex

I need to split up a JSONPath path into 3 parts if it has a separator. A separator would be an indicator of an array.

For example:

$.Colors[*].name

Would need to become:

Before: "$.Colors"
Separator: "[*]"
After: ".name"

In the event that there's multiple:

like:

$.Colors[*].Color[*].name

It would need to take the first:

Before: "$.Colors"
Separator: "[*]"
After: ".Color[*].name"

I also want this to work on filters:

$.Colors[?(@.type == 'Primary')].Color[*].name

It would split on that filter value.

Before: "$.Colors"
Separator: "[?(@.type == 'Primary')]"
After: ".Color[*].name"

My attempts have been fruitless thus far:

static private String regexString = "\\[\\*]|\\[\\?\\(.*\\)]";
static private Pattern pattern = Pattern.compile(regexString);
private boolean splittable;
private String pre;
private String post;
private String split;

PathSplitter(String path) {
    Matcher matcher = pattern.matcher(path);
    if (!matcher.find()) {
        splittable = false;
    }
    else {
        splittable = true;
        split = matcher.group(0);
        //pre = matcher.group(1);
        //post = matcher.group(2);

    }
}

Any help would be great!

Upvotes: 1

Views: 123

Answers (1)

Pushpesh Kumar Rajwanshi
Pushpesh Kumar Rajwanshi

Reputation: 18357

The regex you need is this for getting the expected matches as mentioned in your post,

(.*?)(\[[^[\]]*\])(.*)

Here,

  • (.*?) - This part captures the Before part anything as less as possible before the separator pattern and captures the data in group1
  • (\[[^[\]]*\]) - This part captures the separator which starts with literal [ followed by any character other than [ and ] zero or more followed by a closing ]
  • (.*) - Finally this captures the remaining of After part

Regex Demo

Java code,

List<String> list = Arrays.asList("$.Colors[*].name","$.Colors[*].Color[*].name","$.Colors[?(@.type == 'Primary')].Color[*].name");
Pattern p = Pattern.compile("(.*?)(\\[[^\\[\\]]*\\])(.*)");

list.forEach(x -> {
    Matcher m = p.matcher(x);
    if (m.matches()) {
        System.out.println("For string: " + x);
        System.out.println("Before: "+ m.group(1));
        System.out.println("Separator: "+ m.group(2));
        System.out.println("After: "+ m.group(3));
        System.out.println();
    }
});

Prints the following like you expected,

For string: $.Colors[*].name
Before: $.Colors
Separator: [*]
After: .name

For string: $.Colors[*].Color[*].name
Before: $.Colors
Separator: [*]
After: .Color[*].name

For string: $.Colors[?(@.type == 'Primary')].Color[*].name
Before: $.Colors
Separator: [?(@.type == 'Primary')]
After: .Color[*].name

Upvotes: 2

Related Questions