13

Assuming an input string is a well formed duration in the form "1hr 30m", how can I get the 1 and 30 out and into their own variables?

  • You may want to try a site like regexlib.com to look for canned regexes and regular-expressions.info/javascriptexample.html for quick and easy testing. – Mike Chale Aug 6 '12 at 16:11
  • I highly recommend Regex Buddy for building and testing regular expressions. It allows you to test on a variety of regex engines (use Java for SFDC), has a library of expressions and will explain expressions in a step-by-step fashion. I'm not affiliated with the company in any way, just a long time customer. Regex Buddy can be found here: regexbuddy.com – E.J. Wilburn Aug 6 '12 at 20:37
35

Prep work

  1. Build the regular expression (there's lots of web resources on that, but use the Java versions as that's what Apex does under the hood). Eg. \d+h \d+m

  2. Use braces to define the parts you're interested in. (\d+)h (\d+)m

  3. Turn it into a string by escaping any backslashes '(\\d+)h (\\d+)m'

Write the code

  1. Create a Pattern object using your string

  2. Use that to create a Matcher object.

  3. Test to see if you got any matches using the Matcher's matches() function.

  4. If you did, you can get the matches from the Matcher's group() function.

    Pattern p = Pattern.compile('(\\d+)h (\\d+)m');
    Matcher pm = p.matcher( yourString );
    
    if( pm.matches() ){
         hours = pm.group(1);
         minutes = pm.group(2);
    }
    

I'll leave it to you to declare hours and minutes, give them defaults, and to cast them into numerical types if you don't want them as strings.

You can, of course, chain the methods:

    Matcher pm = Pattern.compile('(\\d+)h (\\d+)m').matcher( yourString );

but if you're doing it more than once, you're recompiling the regular expression over and over.

  • NOTE, it's was not obvious to me but you must run pm.matches() to execute the search which then will result in your pm.group(...) being populated. – Daniel Sokolowski Mar 29 '14 at 1:07
2

Here is a slight improvement on this that will return just the hour and minute digits without the preceding 'hr' or 'm'. ie) Returns just the '1' and '30 from the '1hr 30m' sample listed above.

String hours;
String minutes;

// Match the 'xxhr' and 'xxm' where x is either one or two numeric digits
// ie) Return '1hr' and '30m'
//Pattern p = Pattern.compile('([0-9]+hr) ([0-9]+m)');

// Match the hours and minutes without the 'hr' and 'm'. ie) Return '1' and '30'
Pattern p = Pattern.compile('(\\d+)(?=)hr (\\d+)(?=)m');

Matcher pm = p.matcher('1hr 30m');

if( pm.matches() )
{
    hours = pm.group(1);
    minutes = pm.group(2);
}

System.Debug('*** Hours: ' + hours);
System.Debug('*** Minutes: ' + minutes);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.