2

The title is not clear, so I write some sample to explain.

There is a string, which contains many nested {}s:

 /users/{<\w{2,4}\d{3}>id}

You can see I use {} as a placeholder for path variables, and it can have regex inside and which can also have {}.

How to write a regex with java to parse the path pattern, find the {} parts which don't have outer {}. For this example, it should be {<\w{2,4}\d{3}>id}.

Thanks~

UPDATE

The given example is too simple, it can be:

/users/{<\w{2,4}\d{3}>id}/{action}/{<\w{2,4}\d{3}>targetId}

The result should be:

{<\w{2,4}\d{3}>id}
{action}
{<\w{2,4}\d{3}>targetId}

So \\{.*\\} doesn't work.

Freewind
  • 177,284
  • 143
  • 381
  • 649
  • 3
    Do you need to use regex for this? It's getting very close to the realm of parsers, and hand crafting a simple matcher for the {} should be a lot easier, if the regex engine you use can even handle the amount of backreferences you will need. – Dervall Apr 25 '12 at 14:24
  • 2
    This question appears to be an exact duplicate of http://stackoverflow.com/questions/546433/regular-expression-to-match-outer-brackets – NPE Apr 25 '12 at 14:30
  • @aix, thanks, that's the exactly the same question I'm looking for. – Freewind Apr 25 '12 at 14:48
  • What's the expected output in the second example? – Óscar López Apr 25 '12 at 14:57
  • @Oscar, Updated, thanks. – Freewind Apr 25 '12 at 15:19

2 Answers2

1

Will you have such case as /users/{regex1}/{regex2} ?

If yes, in this case "\\{.*\\}" will return "{regex1}/{regex2}". :(

If not "\\{(.*)\\}" is good enough, being greedy you'll go for the whole expression you asked for. ;)

EDIT:

With your edited question then the comment from @aix above was the right answer : Find the `{}` part which doesn't have outer `{}` by regex

He pointed out your problem is similar with the one solved there: Regular Expression to match outer brackets

Community
  • 1
  • 1
Nicocube
  • 2,883
  • 2
  • 18
  • 28
  • The first is solved by a lazy regex and the second by greedy regex. As `Dervall` pointed out a hand-written parser will do the job right. Regex is ill-suited here. – Petar Minchev Apr 25 '12 at 14:33
  • lazy regex will fail according to given use case `/users/{id}`. `"\\{.*?\\}"` would return `{ – Nicocube Apr 25 '12 at 14:41
  • See my updated question. The given sample is too simple, so I add complex one :) – Freewind Apr 25 '12 at 14:53
0

Perhaps I'm misinterpreting your example. But, your second example is:

/users/{<\w{2,4}\d{3}>id}/{action}/{<\w{2,4}\d{3}>targetId}

The result should be:

{<\w{2,4}\d{3}>id}
{action}
{<\w{2,4}\d{3}>targetId}

Are your {}'s that you want always going to be inside a delimiting /? If, so, then you could do this easy enough by splitting on / and then just checking each result:

String test = "/users/{<\\w{2,4}\\d{3}>id}/{action}/{<\\w{2,4}\\d{3}>targetId}";
String[] pieces = test.split("(?<!\\\\)/");
for (String piece : pieces) {
    if (piece.matches("^\\{.*")) {
        /* do whatever */
    }
}

Where I've put in a complicated split assuming that an escaped / isn't a delimiter.

Is this the kind of thing you're looking for?

Mike Ryan
  • 3,754
  • 1
  • 16
  • 22