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);
}
}