Ivan
Ivan

Reputation: 249

Regex separating list of expressions with exceptions

I have a list of expressions (containing symbols) separated by hyphens:

"exp_1-exp_2-exp_3-exp_4-..........."

I can use the regex matcher /([^-]*)-/ and the standard matcher.find() in java to extract the expressions into

and so on.

However, I also want a list of exceptions that should be matched as a whole. For example, I want to have "a_1-b_2" and "c_3-d_4" not to split.

So, if the expression is

"exp_0-a_1-b_2-c_3-d_4-exp_5..."

the matcher should give me the list

How should I modify my regex expression? Or are there better alternatives?

Edit:

A typical example: exp can be \pi_1*b_3 or \sqrt{b_2/b_4}. I assume no minus signs (hyphens) involved. But I want to group terms for example:

String exception ="\sqrt{3}-\sqrt{2}"

So for example, the list may be

"5a^3-\sqrt{3}-\sqrt{2}-\pi_1*b_3"

and I should get

(These are just expressions, NO mathematics involved, I know what I am trying to get.)

Upvotes: 1

Views: 57

Answers (1)

zx81
zx81

Reputation: 41838

Alright, this particular solution is straight out of Match (or replace) a pattern except in situations s1, s2, s3 etc

Here's a simple regex that we will use to split on the correct dashes:

a_\\d-b_\\d|c_\\d-d_\\d|(-)

Each of the two left OR cases (i.e., |) match one of your exceptions. We will ignore these matches. The right side matches and captures dashes to Group 1, and we know they are the right dashes because they were not matched by the expression on the left.

We replace the good dashes with SplitHere, then we split on SplitHere

This program shows how to use the regex (see the results at the bottom of the online demo). Just refine the exception regexes to suit your exact needs.

import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;

class Program {
public static void main (String[] args) throws java.lang.Exception  {

String subject = "exp_0-a_1-b_2-c_3-d_4-exp_5";
Pattern regex = Pattern.compile("a_\\d-b_\\d|c_\\d-d_\\d|(-)");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, "SplitHere");
    else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
String[] splits = replaced.split("SplitHere");
for (String split : splits) System.out.println(split);
} // end main
} // end Program

Output:

exp_0
a_1-b_2
c_3-d_4
exp_5

Reference

  1. How to match pattern except in situations s1, s2, s3

Upvotes: 1

Related Questions