3.14. Replace All Matches

Problem

You want to replace all matches of the regular expression before with the replacement text «after».

Solution

C#

You can use the static call when you process only a small number of strings with the same regular expression:

string resultString = Regex.Replace(subjectString, "before", "after");

If the regex is provided by the end user, you should use the static call with full exception handling:

string resultString = null;
try {
    resultString = Regex.Replace(subjectString, "before", "after");
} catch (ArgumentNullException ex) {
    // Cannot pass null as the regular expression, subject string,
    // or replacement text
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

Construct a Regex object if you want to use the same regular expression with a large number of strings:

Regex regexObj = new Regex("before");
string resultString = regexObj.Replace(subjectString, "after");

If the regex is provided by the end user, you should use the Regex object with full exception handling:

string resultString = null;
try {
    Regex regexObj = new Regex("before");
    try {
        resultString = regexObj.Replace(subjectString, "after");
    } catch (ArgumentNullException ex) {
        // Cannot pass null as the subject string or replacement text
    }
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

VB.NET

You can use the static call when you process only a small number of strings with the same regular expression:

Dim ResultString = Regex.Replace(SubjectString, "before", "after")

If the regex is provided by the end user, you should use the static call with full exception handling:

Dim ResultString As String = Nothing
Try
    ResultString = Regex.Replace(SubjectString, "before", "after")
Catch ex As ArgumentNullException
    'Cannot pass null as the regular expression, subject string,
    'or replacement text
Catch ex As ArgumentException
    'Syntax error in the regular expression
End Try

Construct a Regex object if you want to use the same regular expression with a large number of strings:

Dim RegexObj As New Regex("before")
Dim ResultString = RegexObj.Replace(SubjectString, "after")

If the regex is provided by the end user, you should use the Regex object with full exception handling:

Dim ResultString As String = Nothing
Try
    Dim RegexObj As New Regex("before")
    Try
        ResultString = RegexObj.Replace(SubjectString, "after")
    Catch ex As ArgumentNullException
       'Cannot pass null as the subject string or replacement text
    End Try
Catch ex As ArgumentException
    'Syntax error in the regular expression
End Try

Java

You can use the static call when you process only one string with the same regular expression:

String resultString = subjectString.replaceAll("before", "after");

If the regex or replacement text is provided by the end user, you should use the static call with full exception handling:

try {
    String resultString = subjectString.replaceAll("before", "after");
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
} catch (IllegalArgumentException ex) {
    // Syntax error in the replacement text (unescaped $ signs?)
} catch (IndexOutOfBoundsException ex) {
    // Non-existent backreference used the replacement text
}

Construct a Matcher object if you want to use the same regular expression with a large number of strings:

Pattern regex = Pattern.compile("before");
Matcher regexMatcher = regex.matcher(subjectString);
String resultString = regexMatcher.replaceAll("after");

If the regex or replacement text is provided by the end user, you should use the Matcher object with full exception handling:

String resultString = null;
try {
    Pattern regex = Pattern.compile("before");
    Matcher regexMatcher = regex.matcher(subjectString);
    try {
        resultString = regexMatcher.replaceAll("after");
    } catch (IllegalArgumentException ex) {
        // Syntax error in the replacement text (unescaped $ signs?)
    } catch (IndexOutOfBoundsException ex) {
        // Non-existent backreference used the replacement text
    }
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

JavaScript

result = subject.replace(/before/g, "after");

PHP

$result = preg_replace('/before/', 'after', $subject);

Perl

With the subject string held in the special variable $_, storing the result back into $_:

s/before/after/g;

With the subject string held in the variable $subject, storing the result back into $subject:

$subject =~ s/before/after/g;

With the subject string held in the variable $subject, storing the result into $result:

($result = $subject) =~ s/before/after/g;

Python

If you have only a few strings to process, you can use the global function:

result = re.sub("before", "after", subject)

To use the same regex repeatedly, use a compiled object:

reobj = re.compile("before")
result = reobj.sub("after", subject)

Ruby

result = subject.gsub(/before/, 'after')

Discussion

.NET

In .NET, you will always use the Regex.Replace() method to search and replace with a regular expression. The Replace() method has 10 overloads. Half of those take a string as the replacement text; those are discussed here. The other half take a MatchEvaluator delegate as the replacement, and those are discussed in Recipe 3.16.

The first parameter expected by Replace() is always the string that holds the original subject text you want to search and replace through. This parameter should not be null. Otherwise, Replace() will throw an ArgumentNullException. The return value of Replace() is always the string with the replacements applied.

If you want to use the regular expression only a few times, you can use a static call. The second parameter is then the regular expression you want to use. Specify the replacement text as the third parameter. You can pass regex options as an optional fourth parameter. If your regular expression has a syntax error, an ArgumentException will be thrown.

If you want to use the same regular expression on many strings, you can make your code more efficient by constructing a Regex object first, and then calling Replace() on that object. Pass the subject string as the first parameter and the replacement text as the second parameter. Those are the only required parameters.

When calling Replace() on an instance of the Regex class, you can pass additional parameters to limit the search-and-replace. If you omit these parameters, all matches of the regular expression in the subject string will be replaced. The static overloads of Replace() do not allow these additional parameters; they always replace all matches.

As the optional third parameter, after the subject and replacement, you can pass the number of replacements to be made. If you pass a number greater than one, that is the maximum number of replacements that will be made. For example, Replace(subject, replacement, 3) replaces only the first three regular expression matches, and further matches are ignored. If there are fewer than three possible matches in the string, all matches will be replaced. You will not receive any indication that fewer replacements were made than you requested. If you pass zero as the third parameter, no replacements will be made at all and the subject string will be returned unchanged. If you pass -1, all regex matches are replaced. Specifying a number less than -1 will cause Replace() to throw an ArgumentOutOfRangeException.

If you specify the third parameter with the number of replacements to be made, then you can specify an optional fourth parameter to indicate the character index at which the regular expression should begin to search. Essentially, the number you pass as the fourth parameter is the number of characters at the start of your subject string that the regular expression should ignore. This can be useful when you’ve already processed the string up to a point, and you want to search and replace only through the remainder of the string. If you specify the number, it must be between zero and the length of the subject string. Otherwise, Replace() throws an ArgumentOutOfRangeException. Unlike Match(), Replace() does not allow you to provide a parameter that specifies the length of the substring the regular expression is allowed to search through.

Java

If you only want to search and replace through one string with the same regex, you can call either the replaceFirst() or replaceAll() method directly on your string. Both methods take two parameters: a string with your regular expression and a string with your replacement text. These are convenience functions that call Pattern.compile("before").matcher(subjectString).replaceFirst("after") and Pattern.compile("before").matcher(subjectString).replaceAll("after").

If you want to use the same regex on multiple strings, you should create the Matcher object as explained in Recipe 3.3. Then, call replaceFirst() or replaceAll() on your matcher, passing the replacement text as the only parameter.

There are three different exception classes you have to contend with if the regex and replacement text are provided by the end user. The exception class PatternSyntaxException is thrown by Pattern.compile(), String.replaceFirst(), and String.replaceAll() if the regular expression has a syntax error. IllegalArgumentException is thrown by replaceFirst() and replaceAll() if there’s a syntax error in the replacement text. If the replacement text is syntactically valid but references a capturing group that does not exist, then IndexOutOfBoundsException is thrown instead.

JavaScript

To search and replace through a string using a regular expression, call the replace() function on the string. Pass your regular expression as the first parameter and the string with your replacement text as the second parameter. The replace() function returns a new string with the replacements applied.

If you want to replace all regex matches in the string, set the /g flag when creating your regular expression object. Recipe 3.4 explains how this works. If you don’t use the /g flag, only the first match will be replaced.

PHP

You can easily search and replace through a string with preg_replace(). Pass your regular expression as the first parameter, the replacement text as the second parameter, and the subject string as the third parameter. The return value is a string with the replacements applied.

The optional fourth parameter allows you to limit the number of replacements made. If you omit the parameter or specify -1, all regex matches are replaced. If you specify 0, no replacements are made. If you specify a positive number, preg_replace() will replace up to as many regex matches as you specified. If there are fewer matches, all of them are replaced without error.

If you want to know how many replacements were made, you can add a fifth parameter to the call. This parameter will receive an integer with the number of replacements that were actually made.

A special feature of preg_replace() is that you can pass arrays instead of strings for the first three parameters. If you pass an array of strings instead of a single string as the third parameter, preg_replace() will return an array with the search-and-replace done on all the strings.

If you pass an array of regular expression strings as the first parameter, preg_replace() will use the regular expressions one by one to search and replace through the subject string. If you pass an array of subject strings, all the regular expressions are used on all the subject strings. When searching for an array of regular expressions, you can specify either a single string as the replacement (to be used by all the regexes) or an array of replacements. When using two arrays, preg_replace() walks through both the regex and replacement arrays, using a different replacement text for each regex. preg_replace() walks through the array as it is stored in memory, which is not necessarily the numerical order of the indexes in the array. If you didn’t build the array in numerical order, call ksort() on the arrays with the regular expressions and replacement texts before passing them to preg_replace().

This example builds the $replace array in reverse order:

$regex[0] = '/a/';
$regex[1] = '/b/';
$regex[2] = '/c/';
$replace[2] = '3';
$replace[1] = '2';
$replace[0] = '1';

echo preg_replace($regex, $replace, "abc");
ksort($replace);
echo preg_replace($regex, $replace, "abc");

The first call to preg_replace() displays 321, which is not what you might expect. After using ksort(), the replacement returns 123 as we intended. ksort() modifies the variable you pass to it. Don’t pass its return value (true or false) to preg_replace().

Perl

In Perl, s/// is in fact a substitution operator. If you use s/// by itself, it will search and replace through the $_ variable, storing the result back into $_.

If you want to use the substitution operator on another variable, use the =~ binding operator to associate the substitution operator with your variable. Binding the substitution operator to a string immediately executes the search-and-replace. The result is stored back into the variable that holds the subject string.

The s/// operator always modifies the variable you bind it to. If you want to store the result of the search-and-replace in a new variable without modifying the original, first assign the original string to the result variable, and then bind the substitution operator to that variable. The Perl solution to this recipe shows how you can take those two steps in one line of code.

Use the /g modifier explained in Recipe 3.4 to replace all regex matches. Without it, Perl replaces only the first match.

Python

The sub() function in the re module performs a search-and-replace using a regular expression. Pass your regular expression as the first parameter, your replacement text as the second parameter, and the subject string as the third parameter. The global sub() function does not accept a parameter with regular expression options.

The re.sub() function calls re.compile(), and then calls the sub() method on the compiled regular expression object. This method has two required parameters: the replacement text and the subject string.

Both forms of sub() return a string with all the regular expressions replaced. Both take one optional parameter that you can use to limit the number of replacements to be made. If you omit it or set it to zero, all regex matches are replaced. If you pass a positive number, that is the maximum number of matches to be replaced. If fewer matches can be found than the count you specified, all matches are replaced without error.

Ruby

The gsub() method of the String class does a search-and-replace using a regular expression. Pass the regular expression as the first parameter and a string with the replacement text as the second parameter. The return value is a new string with the replacements applied. If no regex matches can be found, then gsub() returns the original string.

gsub() does not modify the string on which you call the method. If you want the original string to be modified, call gsub!() instead. If no regex matches can be found, gsub!() returns nil. Otherwise, it returns the string you called it on, with the replacements applied.

See Also

Search and Replace with Regular Expressions in Chapter 1 describes the various replacement text flavors.

Recipe 3.15 shows code to make a search-and-replace reinsert parts of the text matched by the regular expression.

Recipe 3.16 shows code to search and replace with replacements generated in code for each regex match instead of using a fixed replacement text for all matches.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset