Complicated logic calls for regex

When is regex the proper tool? One use case is when you try to verify a text, and the verification rules have complicated logic. I found the following Java method in real production code. It verifies that a time zone designator adheres to the ISO 8601 standard:

public boolean isTimeDesignator(String designator) {
  if (designator.equals("Z")) {
    return true;
  } else if (designator.startsWith(" ") && designator.trim().equals("UTC")) {
    return true;
  } else if (designator.startsWith("+") || designator.startsWith("-")) {
    try {
      int hour = Integer.parseInt(designator.substring(1,3));
      int minute;
      if (3 == designator.length()) {
        minute = 0;
      } else if (5 == designator.length()) {
        minute = Integer.parseInt(designator.substring(3,5));
      } else if (6 == designator.length() && ':' == designator.charAt(3)) {
        minute = Integer.parseInt(designator.substring(4,6));
      } else {
        return false;
      }
      return 0 <= hour && 24 >= hour && 0 <= minute && 59 >= minute;
    } catch (NumberFormatException e) {
      return false;
    }
  }
    
  return false;
}

Only counting the if and else, there are 7 ways the control flow can traverse this code. Adding the NumberFormatException there’s another 3. These ten routes need to be covered by tests.

In ISO 8601, global time is always represented as an offset to Coordinated Universal Time, abbreviated UTC. UTC is informally equivalent to the Greenwich Mean Time, also known as GMT. The designator is an offset in hours and minutes to UTC. Hours are mandatory, but minutes and a colon in-between minutes and hours are optional. Offset zero can be represented as a space and then ‘UCT’ or as ‘Z’. Complicated?

In regex — still in Java — it’s rather crisp to verify:

public boolean isTimeDesignator(String designator) {
  return designator.matches("Z| +UTC|[+-]([01]\\d|2[0-4])(:?[0-5]\\d)?");
}

The latter solution may seem cryptic, for people without experience in regex. But if you think about it, the first solution is cryptic for anyone not proficient in imperative coding. And if you ask me, the first solution is hard to follow for anybody. To understand a regex, you need to understand regex. That’s a tautology. With regex in your repertoire, some problem classes can be solved much more smoothly and the solutions are easier to maintain.

Advertisements

1 Response to “Complicated logic calls for regex”


  1. 1 Peter Jaric (@peterjaric) 2011-09-16 at 10.33

    One could argue that the Java version is needlessly complicated, though. It could be refactored into something smaller, but your point may still hold of course.


Comments are currently closed.




%d bloggers like this: