1

I'm trying to use regex to extract some information from a String.

I'm working on a program that needs to take a user inputted timeframe, and I need to seperate out the string into each of the units of time(years,months, weeks,days, hours and minutes.)

Example of the String: 1y30d would represent 1 year 30 days. 1y1m30mi would be 1 year 1 month 30 minutes

Any idea how I would go about this? I'm guessing something with regex would do it, but I have never really used regex, so I don't know where to start.

Thanks for any help.

1

1 Answer 1

3

If you want to match a pattern like:

1y2m3d45h6mi7s

You could use the following regex (online demo here):

(?:(\d+)y)?(?:(\d+)m(?!i))?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)mi)?(?:(\d+)s)?

As you can see, it consists in several parts like (?:(\d+)X)?, where X is the character for the time period you want to match. It means:

(?:           open parenthesis, for "non-matching group"
    (\d+)     any number of digits
    X         followed by the character 'X'
)?            and everything is optional

Also, for month, (?:(\d+)m(?!i))?, there is a negative lookahead to make it consider 1mi one minute instead of one month plus the char i (from another information, that is not the date).

And some Java code to work with it (online demo here):

public static void main(String[] args) throws java.lang.Exception {
    parseInformation("1y30d");
    parseInformation("1y2m30mi");
    parseInformation("1y1mi");
    parseInformation("1y2m3d4h5mi6s");
}

public static void parseInformation(String information) {
    Pattern p = Pattern.compile("(?:(\\d+)y)?(?:(\\d+)m(?!i))?(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)mi)?(?:(\\d+)s)?");
    Matcher m = p.matcher(information);
    while (m.find()) {
        if (m.group().isEmpty()) { continue; /* found nothing, go on */ }
        System.out.println(information + " found: '"+m.group()+"'");
        System.out.println("\t" + m.group(1) + " years");
        System.out.println("\t" + m.group(2) + " months");
        System.out.println("\t" + m.group(3) + " days");
        System.out.println("\t" + m.group(4) + " hours");
        System.out.println("\t" + m.group(5) + " minutes");
        System.out.println("\t" + m.group(6) + " seconds");
        System.out.println("");
    }

Output:

...
1y2m3d4h5mi6s found: '1y2m3d4h5mi6s'
    1 years
    2 months
    3 days
    4 hours
    5 minutes
    6 seconds
Sign up to request clarification or add additional context in comments.

1 Comment

@M42 You are right, it is safer to consider mi to be minutes instead of month+end of the string. I fixed it, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.