import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Font;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;
/**
* This is a program for trying out regular expressions.
* Java 1.4 or better is required.
*
* @author David Matuszek (original version)
* http://www.cis.upenn.edu/~matuszek/General/RegexTester/regex-tester.html
* @author Guy Lapalme (modified July 2006)
* http://www.iro.umontreal.ca/~lapalme
* - allow Java input
* - allow recovering past input
* - can be used as an Applet or an Application
* @version 2.0
*/
public class RegexTester extends JApplet{
// GUI components
String targetText = "";
String patternText = "";
String javaText = "";
JTextFieldWithMemory targetField = new JTextFieldWithMemory();
JTextFieldWithMemory patternField = new JTextFieldWithMemory();
JTextFieldWithMemory javaField = new JTextFieldWithMemory();
JButton matchesButton = new JButton("matches()");
JButton lookingAtButton = new JButton("lookingAt()");
JButton findButton = new JButton("find()");
JButton resetButton = new JButton("reset()");
JTextArea resultField = new JTextArea(10,60);
Pattern pattern = Pattern.compile("");
Matcher matcher = pattern.matcher("");
boolean errorInPattern = false;
/**
* Lays out the GUI and adds the action listeners.
*/
public void init() {
Font originalFont = getFont();
Font bigFont = new Font("Monospaced", Font.PLAIN, 16);
// Lay out components and set fonts
setLayout(new BorderLayout());
JPanel inputsPanel = new JPanel();
add(BorderLayout.NORTH, inputsPanel);
inputsPanel.setLayout(new BorderLayout());
JPanel labelPanel = new JPanel();
inputsPanel.add(BorderLayout.WEST, labelPanel);
labelPanel.setLayout(new GridLayout(3, 1));
labelPanel.add(new JLabel(" String:"));
labelPanel.add(new JLabel(" Pattern: "));
labelPanel.add(new JLabel(" In Java: "));
JPanel workPanel = new JPanel();
inputsPanel.add(BorderLayout.CENTER, workPanel);
workPanel.setLayout(new GridLayout(3, 1));
workPanel.setFont(bigFont);
workPanel.add(targetField);
workPanel.add(patternField);
workPanel.add(javaField);
JPanel buttonPanel = new JPanel();
inputsPanel.add(BorderLayout.SOUTH,buttonPanel);
buttonPanel.setFont(originalFont);
buttonPanel.setLayout(new GridLayout(1, 4));
buttonPanel.add(matchesButton);
buttonPanel.add(lookingAtButton);
buttonPanel.add(findButton);
buttonPanel.add(resetButton);
JPanel resultsPanel = new JPanel();
add(BorderLayout.SOUTH, resultField);
resultField.setFont(bigFont);
resultField.setEditable(false);
// add Listeners for text fields
targetField.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JTextFieldWithMemory tf = (JTextFieldWithMemory) e.getSource();
String item = (String) tf.getSelectedItem();
//System.out.println("targetField:"+item);
if(tf.setText(item)){
targetText=item;
resetMatcher();
}
}
});
patternField.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JTextFieldWithMemory tf = (JTextFieldWithMemory) e.getSource();
String item = (String) tf.getSelectedItem();
//System.out.println("patternField:"+item);
if(tf.setText(item)){
patternText=item;
javaText=javaVersion(item);
javaField.setText(javaText);
resetMatcher();
}
}
});
javaField.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JTextFieldWithMemory tf = (JTextFieldWithMemory) e.getSource();
String item = (String) tf.getSelectedItem();
//System.out.println("javaField:"+item);
if(tf.setText(item)){
javaText=item;
patternText=patternVersion(item);
patternField.setText(patternText);
resetMatcher();
}
}
});
// Add listeners for buttons
matchesButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
if(checkInput()){
resetButton.setEnabled(false);
showOutput(matcher.matches());
}
}
});
lookingAtButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
if(checkInput()){
boolean success = matcher.lookingAt();
resetButton.setEnabled(success);
showOutput(success);
}
}
});
findButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
if(checkInput()){
boolean success = matcher.find();
showOutput(success);
if(success){
resetButton.setEnabled(success);
} else {
/* Here we handle a possible bug in the Matcher.find()
* method. If the last thing matched by find() is an
* empty string, and then the find() fails, the matcher
* is not reset. In this case, we enable the reset()
* button. Unfortunately, this also means that the reset()
* button will never be disabled when the pattern just
* doesn't match anything in the string.
*/
if (matcher.find())
matcher.reset();
else
resetButton.setEnabled(true);
}
}
}
});
resetButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
resetMatcher();
}
});
// Set the initial state of the GUI
resetButton.setEnabled(false);
patternField.requestFocus();
}
/*
* Check that the matcher is in correct shape and that the pattern is well formed
*/
private boolean checkInput(){
ensureMatcherIsCurrent();
if (errorInPattern) {
resultField.setText("PatternSyntaxException");
return false;
}
return true;
}
/*
* Display the result of the matching
*/
private void showOutput(boolean success){
if (success) {
if (targetField.getText() == null){
resultField.setText("String to be searched is null.");
targetField.select(0,0);
} else {
StringBuffer result =
new StringBuffer().append("start() = ").append(matcher.start())
.append(", end() = ").append(matcher.end());
for (int i = 0; i <= matcher.groupCount(); i++){
result.append("\ngroup(").append(i).append(") = ");
if(matcher.group(i)==null)
result.append("null");
else
result.append('\"').append(matcher.group(i)).append('\"');
}
resultField.setText(""+result);
targetField.select(matcher.start(),matcher.end());
}
} else
resultField.setText("Pattern did not match.");
}
/**
* If the pattern or the target string has changed, resets
* everything; otherwise, does nothing.
*/
private void ensureMatcherIsCurrent() {
if (patternText.equals(patternField.getText()) &&
targetText.equals(targetField.getText()) &&
javaText.equals(javaField.getText()))
return;
resetMatcher();
}
/**
* Converts a String to Java literal string syntax by inserting
* a backslash before characters that must be quoted. Double
* quotes are placed around the output string.
*
* @param regex The string to be converted.
* @result The way this string should be written in Java.
*/
String charsToQuote = "\b\t\n\r\"\'\\";
String lettersOfCharsToQuote ="btnr\"\'\\";
String javaVersion(String regex) {
StringBuffer buffer = new StringBuffer(regex);
for (int i = regex.length() - 1; i >= 0; i--) {
if (charsToQuote.indexOf(buffer.charAt(i)) >= 0) {
buffer.insert(i, '\\');
}
}
return "\""+buffer+"\"";
}
/**
* Converts a Java literal string syntax to a pattern by removing
* the backslash before characters that must be quoted. Double
* quotes are not placed around the output string.
*
* @param javaStr The string to be converted.
* @result The way this string should be written as a pattern.
*/
String patternVersion(String javaStr){
if (javaStr.length()>2 && javaStr.charAt(0)=='\"' && javaStr.charAt(javaStr.length()-1)=='\"'){
StringBuffer buffer = new StringBuffer(javaStr.substring(1,javaStr.length()-1)); // ignore leading and ending "
int l = buffer.length();
int i=0;
while(i=0){
buffer.replace(i,i+2,charsToQuote.substring(k,k+1));
l--;
}
}
}
i++;
}
return ""+buffer;
} else
return javaStr; // return input if not a properly quoted string
}
/**
* Resets the pattern matcher and disables the Reset button.
*/
void resetMatcher() {
patternText = patternField.getText();
targetText = targetField.getText();
try {
errorInPattern = false;
pattern = Pattern.compile(patternText);
}
catch(PatternSyntaxException e) {
errorInPattern = true;
}
matcher = pattern.matcher(targetText);
resultField.setText("");
resetButton.setEnabled(false);
}
/**
* Create a special kind of TextFields which allows to recover past inputs
*/
private static class JTextFieldWithMemory extends JComboBox{
private String text="";
JTextFieldWithMemory(){
setEditable(true);
}
public String getText(){return text;}
public boolean setText(String item){ // return true if the text has changed
if(item.equals(text))return false;
int nb = getItemCount();
for(int k=0;k