More concise solution using regex in java

I'm looking to parse a string and return a number appropriate for a specific person. For example, I could enter Paul

and my method should return 34

.

Currently I am accomplishing this with methods String

substring

(my string will always be formatted the same):

String s = "{name : John, id : '0', fit : '34' }, {name : Paul, id : '0', fit : '34' },{name : Will, id : '0', fit : '24' } ";
String mainGrouping = s.substring(s.indexOf("Paul"));
System.out.println("Main Grouping: "+ mainGrouping);
String subGrouping = mainGrouping.substring(0, mainGrouping.indexOf('}'));
System.out.println("Sub grouping: " + subGrouping);
String fitGrouping= subGrouping.substring(subGrouping.indexOf("fit"));
String finalAnswer = fitGrouping.replaceAll("[^0-9]", "");

System.out.println("final substring: " + finalAnswer);

      

I believe there is a simpler and more concise solution using only one regex. However, I am pretty much unfamiliar with this topic. Is my guess correct? If you could explain your regex solution?

+3


source to share


4 answers


\{name : John, [^\}]*?fit : '(\d+)'.*?\}

      

This regex pattern will match the corresponding value in the first group if applied to your example string.



Just in case, you want to parse JSON strings using this method: it won't work like this. You can't rely on the order of attributes in JSON, to begin with.

If you really want to parse JSON, use the libraries others have talked about. If your example string is legal and you just need to do it for exercise, a regex pattern (or a slightly modified version) must be created.

+1


source


As noted in the comments to the question, it looks like with a little effort your input can be converted to a JSON string and thus can be parsed using a JSON-parsing library like Gson .

In this case, your input string should look like this:



String s = "[{"name" : "John", "id" : 0, "fit" : 34 }, {"name" : "Paul", "id" : 0, "fit" : 34 }, {"name" : "Will", "id" : 0, "fit" : 24 }]";

0


source


Assuming each name

is associated with it fit

and that each name appears before its corresponding one fit

, something like this should work:

Matcher matcher = pattern.compile("name: " + nameToFind + ", .*?fit:'(\d+)'").matcher(s);
String fit = matcher.find() ? matcher.group(1) : null;

      

If you need to do this multiple times, and possibly for different attributes, consider parsing the while line in a map (maps):

Matcher m = Pattern.compile("\\{(.+?)\\}").matcher(s);
Pattern p = Pattern.compile("(\w+?): '?(\\w*?)'?");
Map<String, Map<String, String>> result = new HashMap<>();
while(m.find()) {
    Matcher m2 = p.matcher(m.group(1));
    Map<String, String> map = new HashMap<>();
    while(m2.find()) { map.put(m2.group(1), m2.group(2)); }
    result.put(map.get("name"), map);
}

      

Now, to find the "fit" value for "Paul", you can simply do result.get("Paul").get("fit")

0


source


public class RegexEx {
    public static void main(String[] args) {
        String s = "{name : John, id : '0', fit : '34' }, "
                + "{name : Paul, id : '0', fit : '34' },"
                + "{name : Will, id : '0', fit : '24' } ";
        String name="John";
        String age = getAge(s, name);
        System.out.println(age);


    }

    private static String getAge(String s, String name) {
        String age=null;
        Pattern namePattern = Pattern.compile("name : "+name+"(.*)\\d\\d");
        String[] arr = s.split("}");
        for (String str : arr) {
            Matcher matcher = namePattern.matcher(str);
            while (matcher.find()) {
                Pattern numPattern = Pattern.compile("\\d\\d");
                String match=matcher.group();
                Matcher numMatcher = numPattern.matcher(match);
                if(numMatcher.find())
                age=numMatcher.group();
            }
        }
        return age;
    }
}

      

0


source







All Articles