Complex regex patterns can be difficult to get right first time so here's a simple utility that allows you to test your regex pattern against a line of text to see what happens. The result is displayed in two ways:
RegexTester
This is the code for the RegexTester class
/** * Copyright (c) 2010 keang Ltd. All Rights Reserved. */ package uk.co.keang.regex; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JComboBox; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.WindowConstants; import javax.swing.border.BevelBorder; import javax.swing.border.EmptyBorder; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import uk.co.keang.swingaddons.VariableGridLayout; /** * Allows the input of a regex expression and a test string and then applies the regex * to the test string showing the matches that were made * * @author keang ltd * @version 1.2, 14 May 2010 */ public class RegexTester extends JPanel { private static final long serialVersionUID = -1454574421699687991L; private JComboBox regexCB; private JComboBox inputCB; private JLabel matchLbl; private JTextArea matchTA; private Document matchTADoc; private JButton closeBtn; public RegexTester() { initPanel(); } private void initPanel() { KeyAdapter edited = new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { // clear the current match as soon as a key is pressed clearMatch(); } }; ActionListener inputListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // add the current entry to the list if it isn't already in the list JComboBox cb = (JComboBox)e.getSource(); String text = (String)cb.getSelectedItem(); if ( text != null && text.length() > 0 ) { DefaultComboBoxModel model = ((DefaultComboBoxModel)cb.getModel()); if ( model.getIndexOf(text) < 0 ) model.insertElementAt(text, 0); if ( model.getSize() > 10 ) model.removeElementAt(model.getSize()-1); } } }; setLayout(new BorderLayout(5, 5)); setBorder(new EmptyBorder(10, 10, 10, 10)); // create the regex panel JPanel p = new JPanel(); p.setLayout(new VariableGridLayout(0, 2, 5, 5)); add(p, BorderLayout.CENTER); p.add(new JLabel("Regex", SwingConstants.RIGHT)); regexCB = new JComboBox(); regexCB.setEditable(true); regexCB.addKeyListener(edited); regexCB.addActionListener(inputListener); Dimension d = regexCB.getPreferredSize(); d.width = 200; regexCB.setPreferredSize(d); p.add(regexCB); p.add(new JLabel("Input", SwingConstants.RIGHT)); inputCB = new JComboBox(); inputCB.setEditable(true); inputCB.addKeyListener(edited); inputCB.addActionListener(inputListener); p.add(inputCB); p.add(new JLabel("Matches", SwingConstants.RIGHT)); matchLbl = new JLabel(); matchLbl.setBorder(new BevelBorder(BevelBorder.LOWERED)); matchLbl.setPreferredSize(d); p.add(matchLbl); p.add(new JLabel("")); matchTA = new JTextArea(10, 60); matchTADoc = matchTA.getDocument(); JScrollPane sp = new JScrollPane(matchTA); p.add(sp); // create the buttons panel p = new JPanel(); p.setBorder(new EmptyBorder(15, 20, 0, 20)); p.setLayout(new GridLayout(0, 2, 20, 0)); add(p, BorderLayout.SOUTH); JButton matchBtn = new JButton("Run Regex"); matchBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // run the regex pattern match clearMatch(); // validate the input String regexStr = (String)regexCB.getSelectedItem(); if ( regexStr.length() == 0 ) { JOptionPane.showMessageDialog(RegexTester.this, "The REGEX expression must contain at least 1 character", "No REGEX", JOptionPane.ERROR_MESSAGE); return; } String inputStr = (String)inputCB.getSelectedItem(); if ( inputStr == null || inputStr.length() == 0 ) { JOptionPane.showMessageDialog(RegexTester.this, "The input text must contain at least 1 character", "No Input", JOptionPane.ERROR_MESSAGE); return; } matchPattern(regexStr, inputStr); } }); p.add(matchBtn); closeBtn = new JButton("Close"); closeBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // Close the application clearMatch(); Container top = RegexTester.this.getTopLevelAncestor(); if ( top instanceof Window ) { top.setVisible(false); ((Window)top).dispose(); } } }); p.add(closeBtn); } /** * Clears the match text areas */ private void clearMatch() { matchLbl.setText(""); try { matchTADoc.remove(0, matchTADoc.getLength()); } catch(BadLocationException e1) { e1.printStackTrace(); } } /** * Matches the pattern * * @param regexStr the regex * @param inputStr the string to match */ private void matchPattern(String regexStr, String inputStr) { Pattern pattern; try { pattern = Pattern.compile(regexStr); } catch(Exception e) { matchLbl.setText("<html><font color='red'>Error in REGEX expression</font></html>"); matchTA.append(e.getMessage()); return; } Matcher matcher = pattern.matcher(inputStr); StringBuffer sb = new StringBuffer(); sb.append("<html> "); System.out.println("\nLooking for '"+regexStr+"' in '"+inputStr+"'"); boolean found = false; boolean evenMatch = true; int i = 0; while( matcher.find() ) { int start = matcher.start(); int end = matcher.end(); if ( start > i ) { // add the unmatched text sb.append("<font color='black'>"); sb.append(inputStr.substring(i, start)); sb.append("</font>"); } // add the matched text if ( evenMatch ) sb.append("<font color='red'><b>"); else sb.append("<font color='yellow'><b>"); sb.append(inputStr.substring(start, end)); sb.append("</b></font>"); String str = "\""+matcher.group()+"\" found from " + "index "+matcher.start()+" to "+matcher.end(); matchTA.append(str); matchTA.append("\n"); System.out.println(str); i = end; evenMatch = !evenMatch; found = true; } if ( found ) { if ( i < inputStr.length() ) { // add the remaining unmatched text sb.append("<font color='black'>"); sb.append(inputStr.substring(i, inputStr.length())); sb.append("</font>"); } } else { sb.append("No matches found"); } sb.append("</html>"); matchLbl.setText(sb.toString()); } /** * Sets the text to display on the close button * * @param text the text to display */ public void setCloseButtonText(String text) { closeBtn.setText(text); } /** * Starts the application in a JFrame * @param args */ public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch ( Exception e ) { System.out.println("Failed to set Look and Feel.\n"+e); } JFrame frame = new JFrame("Regex Tester"); frame.add(new RegexTester()); frame.pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension d = frame.getSize(); d.width += 10; d.height += 10; frame.setSize(d); frame.setLocation((screenSize.width-d.width)/2, (screenSize.height-d.height)/2); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.setVisible(true); } }