TutorialTools & LanguagesExamplesBooks & Reference
RegexBuddy Easily use the power of regular expressions in your Java applications with RegexBuddy.
Create and analyze regex patterns with RegexBuddy's intuitive regex building blocks. Implement regexes in your applications with instant Java code snippets. Just tell RegexBuddy what you want to achieve, and copy and paste the auto-generated Java code. Get your own copy of RegexBuddy now.

Java Demo Application using Regular Expressions

Learn how to use the java.util.regex package.

Download the demo application and complete source code

package regexdemo;

import java.util.regex.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Regular Expressions Demo
 * Demonstration showing how to use the java.util.regex package that is part of 
 * the JDK 1.4 and later
 * Copyright (c) 2003 Jan Goyvaerts.  All rights reserved.
 * Visit http://www.regular-expressions.info for a detailed tutorial 
 * to regular expressions.
 * 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
 * http://www.regular-expressions.info
 * @author Jan Goyvaerts
 * @version 1.0
 */

public class FrameRegexDemo extends JFrame {

  // Code generated by the JBuilder 9 designer to create the frame depicted below
  // has been omitted for brevity

  Java Demo Application using Regular Expressions

  /** 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 \A 
   *  is prepended to the regex and an implicit \z 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.
   *  Typing in \( will match a literal ( and \\ matches a literal backslash.
   *  When passing literal strings in your source code, you need to escape
   *  backslashes in strings as usual.
   *  The string "\\(" matches a literal ( character
   *  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
    // 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 regex 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 throws an IllegalArgumentException.
   *  If you reference a group that does not exist (e.g. $4 if there are only
   *  3 groups), throws 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 "\\\\".
   *  This is because backslashes need to be escaped in Java string literals too.
   */
  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("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, (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.  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 $  only match at the start 
      // and the end of the string.  Specify this option to make ^ also match 
      // after line breaks in the string, and make $ match before line breaks.
      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 parentheses 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 parentheses 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.
   *
   *  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("Click Create Objects to create the Matcher object");
    } else {
      // Caling Matcher.find() without any parameters continues the search at
      // Matcher.end().  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 btnReplace notes for the special $-syntax in the replacement text.
   */
  void btnObjReplace_actionPerformed(ActionEvent e) {
    if (regexMatcher == null) {
      textResults.setText("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("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 match.)
   */
  void btnAdvancedReplace_actionPerformed(ActionEvent e) {
    if (regexMatcher == null) {
      textResults.setText("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 parentheses just like replaceAll()
          regexMatcher.appendReplacement(replaceResult, 
                                         regexMatcher.group().toUpperCase());
        } catch (IllegalStateException ex) {
          // appendReplacement() was called without a prior 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 regex");
    } else {
      printSplitArray(compiledRegex.split(textSubject.getText() /*, Limit*/));
    }
  }
}

// ActionListener classes generated by JBuilder 9 have been omitted for brevity

Make a Donation

Did this website just save you a trip to the bookstore? Please make a donation to support this site, and you'll get a lifetime of advertisement-free access to this site!

Regex Tools
grep
PowerGREP
RegexBuddy
General Applications
EditPad Pro
Languages & Libraries
Delphi
GNU (Linux)
Java
JavaScript
.NET
PCRE (C/C++)
Perl
PHP
POSIX
Python
REALbasic
Ruby
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
XQuery & XPath
Databases
MySQL
Oracle
PostgreSQL
More Information
Introduction
Quick Start
Tutorial
Tools and Languages
Examples
Books
Reference
Print PDF
About This Site
RSS Feed

 

PowerGREP 3
PowerGREP PowerGREP is probably the most powerful regex-based text processing tool available today. A knowledge worker's Swiss army knife for searching through, extracting information from, and updating piles of files.
Use regular expressions to search through large numbers of text and binary files, such as source code, correspondence, server or system logs, reference texts, archives, etc. Quickly find the files you are looking for, or extract the information you need. Look through just a handful of files, or thousands of files and folders.
Perform comprehensive text and binary replacement operations for easy maintenance of websites, source code, reports, etc. Preview replacements before modifying files, and stay safe with flexible backup and undo options.
Work with plain text files, Unicode files, binary files, files stored in zip archives, and even MS Word documents, Excel spreadsheets and PDF files. Runs on Windows 98, ME, NT4, 2000, XP & Vista.
More information
Download PowerGREP now