0

How can I match a pattern in a string that has linebreaks? e.g.

requisition({"title":"my json", "items" : [{ "A": "a", "B": "b"} ] }) 

I Want to catch this only

{"title":"my json", "items" : [{ "A": "a", "B": "b"} ] } 

I tried something like

String pattern = ".*(\\{.*\\}).*"; Pattern r = Pattern.compile(pattern, Pattern.DOTALL); 

But no sucess. Any sugestions?

Just to make more clear. This is my input

6
  • "No success". Does it fail? Do you get a wrong match? Which one? Am I right in assuming you capturing everything starting from "A"...? Commented Nov 26, 2012 at 21:28
  • @Reimeus, it's a JSON parser implementation what i'm trying to do Commented Nov 26, 2012 at 21:29
  • You always have an input is this format? I mean, it is always a function call with some JSON object as parameter? In this case, can't you use substring? Commented Nov 26, 2012 at 21:31
  • You really shouldn't use regex for free-form JSON parsing. Is this what your input will always look like? Commented Nov 26, 2012 at 21:34
  • @m.buettner, it captures a wrong pattern. I wanted the whole JSON in one string but it captures only a string like "{"m":"farm9.staticflickr.com/8489/8222175522_0b4a4734fe_m.jpg"}," Commented Nov 26, 2012 at 21:38

1 Answer 1

1

The problem with a single JSON object as the input is simple: your first .* is greedy. So it consumes everything until the last { that is still followed by a }. If you made that .* ungreedy (or left it out), you should get the full JSON object:

String pattern = ".*?(\\{.*\\}).*"; 

But you can (and should) leave out the beginning and trailing repetitions completely:

String pattern = "\\{.*\\}"; 

Then you don't even need to capture anything. Note that this has to be used with find instead of matches.

However, your input has multiple JSON objects. And this is where you get problems with regular expressions. Some engines support constructs that allow correct nesting of brackets (to check which ones actually belong together). But those regexes can easily get ugly and not maintainable.

You are better off, walking the string manually, and keeping count of the current nesting level. Whenever you get back to the top-level you just cut off a substring (from the corresponding opening bracket to your current position).

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

2 Comments

Thank you. I'm used to programming in Python and I like RE power to solve problems but in this particular problem I think the best solutions is something like String sub = s.substring(s.indexOf("{"), s.lastIndexOf("}")+1);
@Medeiros yes, for a single JSON object, that is probably the best (and the most readable) solution. However, it still won't solve your problem for a file containing a list of JSON objects.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.