1

Let's say for example that I have a regular expression like this:

"The quick (red|brown|blue|yellow) fox (jumps|leaps) over the lazy (dog|cat)."

This regex has 3 grouped components - if it's matched against a given string, the regex api would allow you to easily extract the value inside each group.

Now let's say I have 3 strings:

["red", "leaps","cat"]

If we make the assumption that all the characters in the regex that are not inside groups are just literal text characters - is there a way to then insert each of those 3 strings into the corresponding group in the original regex, resulting in an output string that combines the non-grouped portion of the regex? In this case, resulting in "The quick red fox leaps over the lazy cat." Preferably, without needing to have a string that has already matched the regex.

I'm looking to do this in Java - I'm quite sure java.util.regex doesn't support this, but I thought maybe there would be a 3rd party lib out there that could allow this to be done. Can anyone give me some pointers?

ekad
  • 14,436
  • 26
  • 44
  • 46
mpobrien
  • 4,922
  • 1
  • 33
  • 35
  • Why not use a template library? What purpose do you have in mind? – Greg Bacon Nov 28 '09 at 22:56
  • Is the regex string consistent? Or is it allowed to have something like `"The quick %s fox %s over the lazy %s."` ? – BalusC Nov 28 '09 at 23:37
  • I'm looking to do something sort of like django's reverse() for url mappings. Django lets you map regular expressions to callables, and when you use reverse(), the groups become params to the callable. Example: /user/(\d+)/ maps to home(user_id), so reverse(home, 12) returns "/user/12/" (basically, returns the URL that would map to it). Now that I've dug up the code to django, it looks like they are using a rather complex (and interesting!) bit of code which manually parses a regex to produce an object that can generate the reversed URL mapping from an arg list. I may just reimplement in java. – mpobrien Nov 29 '09 at 02:28

2 Answers2

1

Most regex implementations allow you to do something like this in a search and replace:

s/The quick (red|brown|blue|yellow) fox (jumps|leaps) over the lazy (dog|cat)/The quick $1 fox $2 over the lazy $3/
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
1

As long as you can do without nested capturing groups you can simply use more regex to retrieve the literals:

String[] strings = new String[] { "red", "leaps", "dog" };
String[] literals = new String("The quick (red|brown|blue|yellow) fox " +
    "(jumps|leaps) over the lazy (dog|cat).").split("(?=[^\\\\])\\(.*?\\)");

StringBuilder sb = new StringBuilder(literals[0]);
for(int i = 0; i < strings.length; i++) {
    sb.append(strings[i]);
    sb.append(literals[i + 1]);
}

// => sb.toString();
Josef Pfleger
  • 74,165
  • 16
  • 97
  • 99