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