1

I have a image drawed on client and i need send it to server in json format

example of object json (this image has 3 lines)

{"lines":[
    [[44,23.8],[44,24.8],[44,26.8],[44,27.8],[44,28.8],[44,31.8],[44,32.8],[44,33.8],[44,34.8],[44,38.8],[44,39.8],[44,41.8],[43,44.8],[43,46.8]],
    [[251,30.8],[252,30.8],[266,30.8],[274,30.8],[288,30.8],[298,30.8],[311,30.8],[320,30.8],[335,30.8],[339,29.8],[345,29.8],[352,28.8],[353,28.8]],
    [[131,144.8],[134,144.8],[135,144.8],[140,142.8],[142,141.8],[153,137.8],[167,134.8],[182,131.8],[199,126.8],[213,123.8],[228,120.8],[245,115.8]]
]}

i parse json object by following code on the server side:

private static List<List<Point>> extractSignature(String jsonEncoding) { 
    List<List<Point>> lines = new ArrayList<List<Point>>(); 
    Matcher lineMatcher = Pattern.compile("(\\[(?:,?\\[-?[\\d\\.]+,-?[\\d\\.]+\\])+\\])").matcher(jsonEncoding);
    while (lineMatcher.find()) { 
        Matcher pointMatcher = Pattern.compile("\\[(-?[\\d\\.]+),(-?[\\d\\.]+)\\]").matcher(lineMatcher.group(1)); 
        List<Point> line = new ArrayList<Point>(); 
        lines.add(line); 
        while (pointMatcher.find()) {
            line.add(new Point(Float.parseFloat(pointMatcher.group(1)), Float.parseFloat(pointMatcher.group(2)))); 
        } 
    }
    return lines; 
} 

it works well but i got the exception (on lineMatcher.find()) when the image is so big (json object is long)

8 déc. 2015 13:17:32 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: "Servlet.service()" pour la servlet jsp a généré une exception
java.lang.StackOverflowError
    at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
    at java.util.regex.Pattern$Curly.match0(Pattern.java:3760)
    at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
    at java.util.regex.Pattern$Ques.match(Pattern.java:3691)
    at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3366)
    at java.util.regex.Pattern$Curly.match0(Pattern.java:3782)
    at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
    at java.util.regex.Pattern$Ques.match(Pattern.java:3691)
    ...

my work around for this problem by using the following code but I do not think it is good solution

    int idxEnd = jsonEncoding.indexOf("]]");
    while(idxEnd >= 0) {
        String _line = jsonEncoding.substring(0, idxEnd + 2);
        int idxBegin = _line.lastIndexOf("[["); // cas [[[
        _line = _line.substring(idxBegin);
        Matcher pointMatcher = Pattern.compile("\\[(-?[\\d\\.]+),(-?[\\d\\.]+)\\]").matcher(_line); 
        List<Point> line = new ArrayList<Point>(); 
        lines.add(line); 
        while (pointMatcher.find()) {
            line.add(new Point(Float.parseFloat(pointMatcher.group(1)), Float.parseFloat(pointMatcher.group(2)))); 
        } 
        jsonEncoding = jsonEncoding.substring(idxEnd + 3);
        idxEnd = jsonEncoding.indexOf("]]");
    }   

So my question about above regular expression: (\\[(?:,?\\[-?[\\d\\.]+,-?[\\d\\.]+\\])+\\])

could be changed to make it work?

thanks a lot

dsea
  • 75
  • 3
  • 16
  • I think this can help http://stackoverflow.com/questions/7509905/java-lang-stackoverflowerror-while-using-a-regex-to-parse-big-strings – Viraj Nalawade Dec 08 '15 at 12:23
  • 5
    If you have a JSON string, why not use any JSON parser to manipulate it? A regex is not the best JSON friend and Java regex is prone to stackoverflow issues if it is "complex" enough for that. – Wiktor Stribiżew Dec 08 '15 at 12:26
  • The best I could come up with is [`(\[\[-?[\d.,]+\](?:,\[-?[\d.,]+\])+\])`](https://regex101.com/r/gP7tM1/1). I would not use a regex here though. – Wiktor Stribiżew Dec 08 '15 at 12:34
  • @stribizhev: ah, there is pb with your regex: https://regex101.com/r/gP7tM1/2 – dsea Dec 08 '15 at 14:48
  • @dsea: Sure, as I said, a regex is not the right way to proceed. – Wiktor Stribiżew Dec 08 '15 at 14:50

1 Answers1

0

So my question about above regular expression: (\\[(?:,?\\[-?[\\d\\.]+,-?[\\d\\.]+\\])+\\])

could be changed to make it work?

Given the sample data in your question and in regex101.com/r/gP7tM1/2, you could simplify the expression to the not equivalent, but sufficient (\[\[-?\d.+?\]\]), i. e.
Pattern.compile("(\\[\\[-?\\d.+?\\]\\])").

Armali
  • 18,255
  • 14
  • 57
  • 171