blob: 8e78add3a0e88732fbdee02fcbd7f1d7e895e82e [file] [log] [blame]
package regexdemo;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import org.apache.log4j.Logger;
/**
* <p>Regular Expressions Demo</p>
* <p>Demonstration showing how to use the java.util.regex package that is part of JDK 1.4 and later</p>
* <p>Copyright (c) 2003 Jan Goyvaerts. All rights reserved.</p>
* <p>Visit <A HREF="http://www.regular-expressions.info">http://www.regular-expressions.info</A>
* for a detailed tutorial to regular expressions.</p>
* <p>This source code is provided for educational purposes only, without any warranty of any kind.
* Distribution of this source code and/or the application compiled from this source code is prohibited.
* Please refer everybody interested in getting a copy of the source code to
* <A HREF="http://www.regular-expressions.info">http://www.regular-expressions.info</A>.</p>
* @author Jan Goyvaerts
* @version 1.0
*/
public class FrameRegexDemo extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JSplitPane jSplitPane1 = new JSplitPane();
JSplitPane jSplitPane2 = new JSplitPane();
JPanel jPanel1 = new JPanel();
BorderLayout borderLayout2 = new BorderLayout();
JPanel jPanel2 = new JPanel();
JLabel jLabel1 = new JLabel();
BorderLayout borderLayout3 = new BorderLayout();
JLabel jLabel2 = new JLabel();
JTextArea textRegex = new JTextArea();
JPanel jPanel3 = new JPanel();
GridLayout gridLayout1 = new GridLayout();
JCheckBox checkDotAll = new JCheckBox();
JCheckBox checkCanonEquivalence = new JCheckBox();
JCheckBox checkMultiLine = new JCheckBox();
JCheckBox checkCaseInsensitive = new JCheckBox();
JPanel jPanel4 = new JPanel();
BorderLayout borderLayout4 = new BorderLayout();
JPanel jPanel5 = new JPanel();
JPanel jPanel6 = new JPanel();
GridLayout gridLayout2 = new GridLayout();
JButton btnMatch = new JButton();
JButton btnSplit = new JButton();
JButton btnObjects = new JButton();
JButton btnNextMatch = new JButton();
JButton btnObjReplace = new JButton();
JButton btnObjSplit = new JButton();
JButton btnReplace = new JButton();
JLabel jLabel3 = new JLabel();
BorderLayout borderLayout5 = new BorderLayout();
JLabel jLabel4 = new JLabel();
JTextArea textSubject = new JTextArea();
JPanel jPanel8 = new JPanel();
GridLayout gridLayout3 = new GridLayout();
BorderLayout borderLayout6 = new BorderLayout();
JPanel jPanel7 = new JPanel();
JLabel jLabel5 = new JLabel();
JTextArea textReplace = new JTextArea();
JPanel jPanel9 = new JPanel();
GridLayout gridLayout4 = new GridLayout();
JPanel jPanel10 = new JPanel();
JPanel jPanel11 = new JPanel();
BorderLayout borderLayout7 = new BorderLayout();
BorderLayout borderLayout8 = new BorderLayout();
JLabel jLabel6 = new JLabel();
JTextArea textResults = new JTextArea();
JLabel jLabel7 = new JLabel();
JTextArea textReplaceResults = new JTextArea();
private Logger log = Logger.getLogger(this.getClass());
private Component launchPoint = null;
//Construct the frame
public FrameRegexDemo() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void setLaunchPoint(Component launchPoint) {
this.launchPoint = launchPoint;
}
//Component initialization
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setFont(new java.awt.Font("Dialog", 0, 12));
this.setSize(new Dimension(629, 523));
this.setTitle("Regular Expressions Demo");
jPanel1.setAlignmentY((float) 0.5);
jPanel1.setLayout(borderLayout2);
jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setBottomComponent(jSplitPane2);
jSplitPane1.setLeftComponent(jPanel1);
jSplitPane1.setRightComponent(null);
jPanel2.setLayout(borderLayout3);
jLabel1.setAlignmentX((float) 0.0);
jLabel1.setMinimumSize(new Dimension(97, 15));
jLabel1.setLabelFor(textRegex);
jLabel1.setText("Regular Expression:");
jLabel2.setText("Visit http://www.regular-expressions.info for a complete regex tutorial");
textRegex.setFont(new java.awt.Font("Monospaced", 0, 12));
textRegex.setBorder(BorderFactory.createLoweredBevelBorder());
textRegex.setText("t[a-z]+");
textRegex.setLineWrap(true);
jPanel3.setLayout(gridLayout1);
gridLayout1.setColumns(2);
gridLayout1.setHgap(2);
gridLayout1.setRows(2);
gridLayout1.setVgap(2);
checkDotAll.setText("Dot matches newlines");
checkCanonEquivalence.setText("Ignore differences in Unicode encoding");
checkMultiLine.setText("^ and $ match at embedded newlines");
checkCaseInsensitive.setText("Case insensitive");
contentPane.setPreferredSize(new Dimension(438, 142));
jPanel4.setLayout(borderLayout4);
jPanel6.setAlignmentX((float) 0.5);
jPanel6.setLayout(borderLayout5);
jPanel5.setLayout(gridLayout2);
gridLayout2.setColumns(5);
gridLayout2.setHgap(2);
gridLayout2.setRows(2);
gridLayout2.setVgap(2);
btnMatch.setText("Match Test");
btnMatch.addActionListener(new FrameRegexDemo_btnMatch_actionAdapter(this));
btnSplit.setText("Split");
btnSplit.addActionListener(new FrameRegexDemo_btnSplit_actionAdapter(this));
btnObjects.setAlignmentY((float) 0.5);
btnObjects.setActionCommand("Create Objects");
btnObjects.setText("Create Objects");
btnObjects.addActionListener(new FrameRegexDemo_btnObjects_actionAdapter(this));
btnNextMatch.setText("Next Match");
btnNextMatch.addActionListener(new FrameRegexDemo_btnNextMatch_actionAdapter(this));
btnObjReplace.setSelected(false);
btnObjReplace.setText("Obj Replace");
btnObjReplace.addActionListener(new FrameRegexDemo_btnObjReplace_actionAdapter(this));
btnObjSplit.setText("Obj Split");
btnObjSplit.addActionListener(new FrameRegexDemo_btnObjSplit_actionAdapter(this));
btnReplace.setText("Replace");
btnReplace.addActionListener(new FrameRegexDemo_btnReplace_actionAdapter(this));
jLabel3.setPreferredSize(new Dimension(0, 0));
jLabel3.setRequestFocusEnabled(true);
jLabel3.setText("");
jLabel4.setLabelFor(textSubject);
jLabel4.setText("Test Subject:");
textSubject.setBorder(BorderFactory.createLoweredBevelBorder());
textSubject.setToolTipText("");
textSubject.setText("This is the default test subject for our regex test.");
textSubject.setLineWrap(true);
textSubject.setWrapStyleWord(true);
jPanel8.setLayout(gridLayout3);
gridLayout3.setColumns(2);
gridLayout3.setHgap(4);
jPanel7.setLayout(borderLayout6);
jLabel5.setMaximumSize(new Dimension(89, 15));
jLabel5.setLabelFor(textReplace);
jLabel5.setText("Replacement Text:");
textReplace.setBorder(BorderFactory.createLoweredBevelBorder());
textReplace.setToolTipText("");
textReplace.setText("replacement");
textReplace.setLineWrap(true);
textReplace.setWrapStyleWord(true);
borderLayout4.setVgap(4);
borderLayout2.setVgap(4);
borderLayout1.setHgap(0);
borderLayout1.setVgap(0);
jPanel9.setLayout(gridLayout4);
gridLayout4.setColumns(2);
gridLayout4.setHgap(4);
jSplitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
jPanel10.setLayout(borderLayout7);
jPanel11.setLayout(borderLayout8);
jLabel6.setToolTipText("");
jLabel6.setLabelFor(textResults);
jLabel6.setText("Results:");
textResults.setBorder(BorderFactory.createLoweredBevelBorder());
textResults.setText("");
textResults.setLineWrap(true);
textResults.setWrapStyleWord(true);
jLabel7.setLabelFor(textReplaceResults);
jLabel7.setText("Replacement Results:");
textReplaceResults.setBorder(BorderFactory.createLoweredBevelBorder());
textReplaceResults.setText("");
textReplaceResults.setLineWrap(true);
textReplaceResults.setWrapStyleWord(true);
jLabel8.setRequestFocusEnabled(true);
jLabel8.setText("");
btnAdvancedReplace.setText("Advanced Replace");
btnAdvancedReplace.addActionListener(new FrameRegexDemo_btnAdvancedReplace_actionAdapter(this));
contentPane.add(jSplitPane1, BorderLayout.CENTER);
jSplitPane1.add(jSplitPane2, JSplitPane.RIGHT);
jSplitPane1.add(jPanel1, JSplitPane.LEFT);
jPanel1.add(jPanel2, BorderLayout.NORTH);
jPanel2.add(jLabel1, BorderLayout.CENTER);
jPanel2.add(jLabel2, BorderLayout.EAST);
jPanel1.add(textRegex, BorderLayout.CENTER);
jPanel1.add(jPanel3, BorderLayout.SOUTH);
jPanel3.add(checkDotAll, null);
jPanel3.add(checkCaseInsensitive, null);
jPanel3.add(checkMultiLine, null);
jPanel3.add(checkCanonEquivalence, null);
jSplitPane2.add(jPanel4, JSplitPane.LEFT);
jPanel4.add(jPanel5, BorderLayout.SOUTH);
jPanel5.add(btnMatch, null);
jPanel5.add(jLabel3, null);
jPanel5.add(jLabel8, null);
jPanel5.add(btnReplace, null);
jPanel5.add(btnSplit, null);
jPanel5.add(btnObjects, null);
jPanel5.add(btnNextMatch, null);
jPanel5.add(btnObjReplace, null);
jPanel5.add(btnAdvancedReplace, null);
jPanel5.add(btnObjSplit, null);
jPanel6.add(jLabel4, BorderLayout.NORTH);
jPanel6.add(textSubject, BorderLayout.CENTER);
jPanel4.add(jPanel8, BorderLayout.CENTER);
jPanel8.add(jPanel6, null);
jSplitPane1.setDividerLocation(150);
jSplitPane2.setDividerLocation(200);
jPanel8.add(jPanel7, null);
jPanel7.add(jLabel5, BorderLayout.NORTH);
jPanel7.add(textReplace, BorderLayout.CENTER);
jSplitPane2.add(jPanel9, JSplitPane.RIGHT);
jPanel9.add(jPanel10, null);
jPanel10.add(jLabel6, BorderLayout.NORTH);
jPanel10.add(textResults, BorderLayout.CENTER);
jPanel9.add(jPanel11, null);
jPanel11.add(jLabel7, BorderLayout.NORTH);
jPanel11.add(textReplaceResults, BorderLayout.CENTER);
}
//Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
// System.exit(0);
log .debug("Closing");
this.setVisible(false);
this.launchPoint.setEnabled(true);
}
}
/** The easiest way to check if a particular string matches a regular expression
* is to simply call String.matches() passing the regular expression to it.
* It is not possible to set matching options this way, so the checkboxes
* in this demo are ignored when clicking btnMatch.<p>
*
* One disadvantage of this method is that it will only return true if the regex
* matches the *entire* string. In other words, an implicit caret is prepended to
* the regex and an implicit dollar sign is appended to it.
* So you cannot use matches() to test if a substring anywhere in the string
* matches the regex.<p>
*
* Note that when typing in a regular expression into textSubject,
* backslashes are interpreted at the regex level.
* So typing in \( will match a literal ( character and \\ matches a literal backslash.
* When passing literal strings in your source code, you need to escape backslashes in strings as usual.
* So the string "\\(" matches a literal ( and "\\\\" matches a single literal backslash.
*/
void btnMatch_actionPerformed(ActionEvent e) {
textReplaceResults.setText("n/a");
// Calling the Pattern.matches static method is an alternative way to achieve the same
// if (Pattern.matches(textRegex.getText(), textSubject.getText())) {
try {
if (textSubject.getText().matches(textRegex.getText())) {
textResults.setText("The regex matches the entire subject");
}
else {
textResults.setText("The regex does not match the entire subject");
}
} catch (PatternSyntaxException ex) {
textResults.setText("You have an error in your regular expression:\n" +
ex.getDescription());
}
}
/** The easiest way to perform a regular expression search-and-replace on a string
* is to call the string's replaceFirst() and replaceAll() methods.
* replaceAll() will replace all substrings that match the regular expression
* with the replacement string, while replaceFirst() will only replace the first match.<p>
*
* Again, you cannot set matching options this way, so the checkboxes
* in this demo are ignored when clicking btnMatch.<p>
*
* In the replacement text, you can use $0 to insert the entire regex match,
* and $1, $2, $3, etc. for the backreferences (text matched by the part in the regex
* between the first, second, third, etc. pair of round brackets)<br>
* \$ inserts a single $ character.<p>
*
* $$ or other improper use of the $ sign will raise an IllegalArgumentException.
* If you reference a group that does not exist (e.g. $4 if there are only 3 groups),
* will raise an IndexOutOfBoundsException. Be sure to properly handle these exceptions
* if you allow the end user to type in the replacement text.<p>
*
* Note that in the memo control, you type \$ to insert a dollar sign,
* and \\ to insert a backslash. If you provide the replacement string as a
* string literal in your Java code, you need to use "\\$" and "\\\\" respectively.
* This is because backslashes need to be escaped in Java string literals as well.
*/
void btnReplace_actionPerformed(ActionEvent e) {
try {
textReplaceResults.setText(
textSubject.getText().replaceAll(textRegex.getText(), textReplace.getText())
);
textResults.setText("n/a");
} catch (PatternSyntaxException ex) {
// textRegex does not contain a valid regular expression
textResults.setText("You have an error in your regular expression:\n" +
ex.getDescription());
textReplaceResults.setText("n/a");
} catch (IllegalArgumentException ex) {
// textReplace contains inapropriate dollar signs
textResults.setText("You have an error in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
} catch (IndexOutOfBoundsException ex) {
// textReplace contains a backreference that does not exist
// (e.g. $4 if there are only three groups)
textResults.setText("You have used a non-existent group in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
}
}
/** Show the results of splitting a string. */
void printSplitArray(String[] array) {
textResults.setText(null);
for (int i = 0; i < array.length; i++) {
textResults.append(Integer.toString(i) + ": \"" + array[i] + "\"\r\n");
}
}
/** The easiest way to split a string into an array of strings is by calling
* the string's split() method. The string will be split at each substring
* that matches the regular expression. The regex matches themselves are
* thrown away.<p>
*
* If the split would result in trailing empty strings, i.e. when the regex matches
* at the end of the string, the trailing empty strings are also thrown away.
* If you want to keep the empty strings, call split(regex, -1). The -1 tells
* the split() method to add trailing empty strings to the resulting array.<p>
*
* You can limit the number of items in the resulting array by specifying a
* positive number as the second parameter to split(). The limit you specify
* it the number of items the array will at most contain. So the regex is applied
* at most limit-1 times, and the last item in the array contains the unsplit
* remainder of the original string. If you are only interested in the first
* 3 items in the array, specify a limit of 4 and disregard the last item.
* This is more efficient than having the string split completely.
*/
void btnSplit_actionPerformed(ActionEvent e) {
textReplaceResults.setText("n/a");
try {
printSplitArray(textSubject.getText().split(textRegex.getText() /*, Limit*/ ));
} catch (PatternSyntaxException ex) {
// textRegex does not contain a valid regular expression
textResults.setText("You have an error in your regular expression:\n" +
ex.getDescription());
}
}
/** Figure out the regex options to be passed to the Pattern.compile()
* class factory based on the state of the checkboxes.
*/
int getRegexOptions() {
int Options = 0;
if (checkCanonEquivalence.isSelected()) {
// In Unicode, certain characters can be encoded in more than one way.
// Many letters with diacritics can be encoded as a single character
// identifying the letter with the diacritic, and encoded as two
// characters: the letter by itself followed by the diacritic by itself
// Though the internal representation is different, when the string is
// rendered to the screen, the result is exactly the same.
Options |= Pattern.CANON_EQ;
}
if (checkCaseInsensitive.isSelected()) {
// Omitting UNICODE_CASE causes only US ASCII characters to be matched case insensitively
// This is appropriate if you know beforehand that the subject string will only contain
// US ASCII characters as it speeds up the pattern matching.
Options |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
}
if (checkDotAll.isSelected()) {
// By default, the dot will not match line break characters.
// Specify this option to make the dot match all characters, including line breaks
Options |= Pattern.DOTALL;
}
if (checkMultiLine.isSelected()) {
// By default, the caret ^, dollar $ as well as \A, \z and \Z
// only match at the start and the end of the string
// Specify this option to make ^ and \A also match after line breaks in the string,
// and make $, \z and \Z match before line breaks in the string
Options |= Pattern.MULTILINE;
}
return Options;
}
/** Pattern constructed by btnObject */
Pattern compiledRegex;
/** Matcher object that will search the subject string using compiledRegex */
Matcher regexMatcher;
JLabel jLabel8 = new JLabel();
JButton btnAdvancedReplace = new JButton();
/** If you will be using a particular regular expression often,
* you should create a Pattern object to store the regular expression.
* You can then reuse the regex as often as you want by reusing the
* Pattern object.<p>
*
* To use the regular expression on a string, create a Matcher object
* by calling compiledRegex.matcher() passing the subject string to it.
* The Matcher will do the actual searching, replacing or splitting.<p>
*
* You can create as many Matcher objects from a single Pattern object
* as you want, and use the Matchers at the same time. To apply the regex
* to another subject string, either create a new Matcher using
* compiledRegex.matcher() or tell the existing Matcher to work on a new
* string by calling regexMatcher.reset(subjectString).
*/
void btnObjects_actionPerformed(ActionEvent e) {
compiledRegex = null;
textReplaceResults.setText("n/a");
try {
// If you do not want to specify any options (this is the case when
// all checkboxes in this demo are unchecked), you can omit the
// second parameter for the Pattern.compile() class factory.
compiledRegex = Pattern.compile(textRegex.getText(), getRegexOptions());
// Create the object that will search the subject string
// using the regular expression.
regexMatcher = compiledRegex.matcher(textSubject.getText());
textResults.setText("Pattern and Matcher objects created.");
} catch (PatternSyntaxException ex) {
// textRegex does not contain a valid regular expression
textResults.setText("You have an error in your regular expression:\n" +
ex.getDescription());
} catch (IllegalArgumentException ex) {
// This exception indicates a bug in getRegexOptions
textResults.setText("Undefined bit values are set in the regex options");
}
}
/** Print the results of a search produced by regexMatcher.find()
* and stored in regexMatcher.
*/
void printMatch() {
try {
textResults.setText("Index of the first character in the match: " +
Integer.toString(regexMatcher.start()) + "\n");
textResults.append("Index of the first character after the match: " +
Integer.toString(regexMatcher.end()) + "\n");
textResults.append("Length of the match: " +
Integer.toString(regexMatcher.end() - regexMatcher.start()) + "\n");
textResults.append("Matched text: " + regexMatcher.group() + "\n");
if (regexMatcher.groupCount() > 0) {
// Capturing parenthesis are numbered 1..groupCount()
// group number zero is the entire regex match
for (int i = 1; i <= regexMatcher.groupCount(); i++) {
String groupLabel = new String("Group " + Integer.toString(i));
if (regexMatcher.start(i) < 0) {
textResults.append(groupLabel + " did not participate in the overall match\n");
} else {
textResults.append(groupLabel + " start: " +
Integer.toString(regexMatcher.start(i)) + "\n");
textResults.append(groupLabel + " end: " +
Integer.toString(regexMatcher.end(i)) + "\n");
textResults.append(groupLabel + " length: " +
Integer.toString(regexMatcher.end(i) - regexMatcher.start(i)) + "\n");
textResults.append(groupLabel + " matched text: " + regexMatcher.group(i) + "\n");
}
}
}
} catch (IllegalStateException ex) {
// Querying the results of a Matcher object before calling find()
// or after a call to find() returned False, throws an IllegalStateException
// This indicates a bug in our application
textResults.setText("Cannot print match results if there aren't any");
} catch (IndexOutOfBoundsException ex) {
// Querying the results of groups (capturing parenthesis or backreferences)
// that do not exist throws an IndexOutOfBoundsException
// This indicates a bug in our application
textResults.setText("Cannot print match results of non-existent groups");
}
}
/** Finds the first match if this is the first search, or if the previous search came up empty.
* Otherwise, it finds the next match after the previous match.<p>
*
* Note that even if you typed in new text for the regex or subject,
* btnNextMatch uses the subject and regex as they were when you clicked btnCreateObjects.
*/
void btnNextMatch_actionPerformed(ActionEvent e) {
textReplaceResults.setText("n/a");
if (regexMatcher == null) {
textResults.setText("Please click Create Objects to create the Matcher object");
} else {
// Caling Matcher.find() without any parameters continues the search at Matcher.end()
// or starts from the beginning of the string if this is the first search using
// the Matcher or if the previous search did not find any (further) matches.
if (regexMatcher.find()) {
printMatch();
} else {
// This also resets the starting position for find() to the start of the subject string
textResults.setText("No further matches");
}
}
}
/** Perform a regular expression search-and-replace using a Matcher object.
* This is the recommended way if you often use the same regular expression
* to do a search-and-replace. You should also reuse the Matcher object
* by calling Matcher.reset(nextSubjectString) for improved efficiency.<p>
*
* You also need to use the Pattern and Matcher objects for the search-and-replace
* if you want to use the regex options such as "case insensitive" or "dot all".<p>
*
* See the notes with btnReplace for the special $-syntax in the replacement text.
*/
void btnObjReplace_actionPerformed(ActionEvent e) {
if (regexMatcher == null) {
textResults.setText("Please click Create Objects to create the Matcher object");
} else {
try {
textReplaceResults.setText(regexMatcher.replaceAll(textReplace.getText()));
} catch (IllegalArgumentException ex) {
// textReplace contains inapropriate dollar signs
textResults.setText("You have an error in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
} catch (IndexOutOfBoundsException ex) {
// textReplace contains a backreference that does not exist
// (e.g. $4 if there are only three groups)
textResults.setText("You have used a non-existent group in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
}
}
}
/** Using Matcher.appendReplacement() and Matcher.appendTail() you can implement
* a search-and-replace of arbitrary complexity. These routines allow you
* to compute the replacement string in your own code. So the replacement text
* can be whatever you want.<p>
*
* To do this, simply call Matcher.find() in a loop. For each match returned
* by find(), call appendReplacement() with whatever replacement text you want.
* When find() can no longer find matches, call appendTail().<p>
*
* appendReplacement() appends the substring between the end of the previous match that
* was replaced with appendReplacement() and the current match. If this is the
* first call to appendReplacement() since creating the Matcher or calling reset(),
* then the appended substring starts at the start of the string. Then, the specified
* replacement text is appended. If the replacement text contains dollar signs,
* they will be interpreted as usual. E.g. $1 is replaced with the match between the
* first pair of capturing parentheses.<p>
*
* appendTail() appends the substring between the end of the previous match that
* was replaceced with appendReplacement() and the end of the string.
* If appendReplacement() was not called since creating the Matcher or calling reset(),
* the entire subject string is appended.<p>
*
* The above means that you should call Matcher.reset() before starting the operation,
* unless you're sure the Matcher is freshly constructed. If certain matches do not
* need to be replaced, simply skip calling appendReplacement() for those matches.
* (Calling appendReplacement() with Matcher.group() as the replacement text will
* only hurt performance and may get you into trouble with dollar signs that may appear
* in the regex match.)
*/
void btnAdvancedReplace_actionPerformed(ActionEvent e) {
if (regexMatcher == null) {
textResults.setText("Please click Create Objects to create the Matcher object");
} else {
// We will store the replacement text here
StringBuffer replaceResult = new StringBuffer();
while (regexMatcher.find()) {
try {
// In this example, we simply replace the regex match with the same text in uppercase.
// Note that appendReplacement parses the replacement text to substitute $1, $2, etc.
// with the contents of the corresponding capturing parenthesis just like replaceAll()
regexMatcher.appendReplacement(replaceResult, regexMatcher.group().toUpperCase());
} catch (IllegalStateException ex) {
// appendReplacement() was called without a preceding successful call to find()
// This exception indicates a bug in your source code
textResults.setText("appendReplacement() called without a prior successful call to find()");
textReplaceResults.setText("n/a");
return;
} catch (IllegalArgumentException ex) {
// Replacement text contains inapropriate dollar signs
textResults.setText("Error in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
return;
} catch (IndexOutOfBoundsException ex) {
// Replacement text contains a backreference that does not exist
// (e.g. $4 if there are only three groups)
textResults.setText("Non-existent group in the replacement text:\n" +
ex.getMessage());
textReplaceResults.setText("n/a");
return;
}
}
regexMatcher.appendTail(replaceResult);
textReplaceResults.setText(replaceResult.toString());
textResults.setText("n/a");
// After using appendReplacement and appendTail, the Matcher object must be reset
// so we can use appendReplacement and appendTail again.
// In practice, you will probably put this call at the start of the routine
// where you want to use appendReplacement and appendTail.
// I did not do that here because this way you can click on the Next Match button
// a couple of times to skip a few matches, and then click on the
// Advanced Replace button to observe that appendReplace() will copy the skipped
// matches unchanged.
regexMatcher.reset();
}
}
/** If you want to split many strings using the same regular expression,
* you should create a Pattern object and call Pattern.split()
* rather than String.split(). Both methods produce exactly the same results.
* However, when creating a Pattern object, you can specify options such as
* "case insensitive" and "dot all".<p>
*
* Note that no Matcher object is used.
*/
void btnObjSplit_actionPerformed(ActionEvent e) {
textReplaceResults.setText("n/a");
if (compiledRegex == null) {
textResults.setText("Please click Create Objects to compile the regular expression");
} else {
printSplitArray(compiledRegex.split(textSubject.getText() /*, Limit*/));
}
}
}
class FrameRegexDemo_btnMatch_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnMatch_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnMatch_actionPerformed(e);
}
}
class FrameRegexDemo_btnReplace_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnReplace_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnReplace_actionPerformed(e);
}
}
class FrameRegexDemo_btnSplit_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnSplit_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnSplit_actionPerformed(e);
}
}
class FrameRegexDemo_btnObjects_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnObjects_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnObjects_actionPerformed(e);
}
}
class FrameRegexDemo_btnNextMatch_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnNextMatch_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnNextMatch_actionPerformed(e);
}
}
class FrameRegexDemo_btnObjReplace_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnObjReplace_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnObjReplace_actionPerformed(e);
}
}
class FrameRegexDemo_btnAdvancedReplace_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnAdvancedReplace_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnAdvancedReplace_actionPerformed(e);
}
}
class FrameRegexDemo_btnObjSplit_actionAdapter implements java.awt.event.ActionListener {
FrameRegexDemo adaptee;
FrameRegexDemo_btnObjSplit_actionAdapter(FrameRegexDemo adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.btnObjSplit_actionPerformed(e);
}
}