Until now, when you had to deal with complex text strings in Java, it was enough to make you cry. You either rigged up an ungodly mess nesting StringTokenizer objects and a thousand calls to indexOf and substring—with the illegible spaghetti code that comes with it—or you had to download and include external Apache libraries, like Jakarta ORO or Regexp. I mean, they got the job done, but ultimately it was just pointlessly bloating the .jar file and adding one more dependency to manually manage when deploying your code to the production server.
But it seems the folks at Sun Microsystems have finally listened to the prayers of those of us who spend our days writing code. I had been meaning to update my environment for a while, so this afternoon I left the new J2SE 1.4 (the famous Merlin) downloading, taking advantage of my connection running half-decently. After a good while downloading megs, I started tinkering with one of the new features I was most eager to try in this version: the new java.util.regex package.
Yes, friends, Java finally has native support for regular expressions, in the purest Perl style. No more messing around with third-party libraries just to validate a sad email or extract IP addresses from a massive block of text.
The logic behind this is quite straightforward, though if you're not used to regular expression syntax, seeing so many backslashes together might give you a mild stroke. Sun has given us two main classes to work the magic: Pattern and Matcher. The first is responsible for compiling the regular expression into memory, and the second is the engine that executes that expression against our text string to see if there are matches.
Here's a quick snippet of what I just typed up in UltraEdit so you can see how it goes. Basically, I wanted to extract the IP addresses from a text line in my cursed log:
import java.util.regex.*;
public class PruebaRegex {
public static void main(String[] args) {
String logLinea = "192.168.1.15 - - [22/Nov/2002:01:45:12 +0100] \"GET /index.html\" 404";
// El patrón para pillar una IP (simplificado, que ya nos conocemos)
String regex = "\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b";
// Compilamos la expresión regular
Pattern patron = Pattern.compile(regex);
// Creamos el buscador contra nuestra cadena de texto
Matcher buscador = patron.matcher(logLinea);
if (buscador.find()) {
System.out.println("¡Bingo! IP encontrada: " + buscador.group());
} else {
System.out.println("Aquí no hay nada, toca seguir buscando.");
}
}
}
You've probably noticed the double backslashes \\. This happens because in Java we have to escape the backslash inside the String syntax before passing it to the regex engine. It's a bit of a headache at first and looks slightly ugly to the eye, but you get used to it quickly.
What's really important is that this runs extremely fast since it's natively integrated. Furthermore, the object-oriented design is very well thought out: compiling the Pattern object costs quite a few clock cycles, but if you do it just once outside the loop and reuse the Matcher object iterating over thousands of lines, you save a ton of memory and CPU. Something that, honestly, my Pentium with 256 MB of RAM appreciates greatly.
After a couple of hours playing with this, I have to admit it's an absolute delight. Java 1.4 brings a lot of other very juicy things, like the new non-blocking I/O (NIO) system or the native logging framework, but for me, just being able to shake off the tyranny of hunting down Jakarta .jars justifies installing the SDK.
Looking ahead, I think this is going to significantly change how we process text in corporate development environments. Anything that standardizes powerful tools and bakes them straight into the virtual machine's core is a massive win by Sun. Obviously, we'll have to see if Java's regular expressions perform as well as pure scripting languages when we feed them gigs and gigs of text to process, but the foundation is solid.
Well, I'm shutting down shop for the night and heading to sleep; I've got classes first thing tomorrow.