3.19. Split a String

Problem

You want to split a string using a regular expression. After the split, you will have an array or list of strings with the text between the regular expression matches.

For example, you want to split a string with HTML tags in it along the HTML tags. Splitting Ilike<b>bold</b>and<i>italic</i>fonts should result in an array of five strings: Ilike, bold, and, italic, and fonts.

Solution

C#

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

string[] splitArray = Regex.Split(subjectString, "<[^<>]*>");

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

string[] splitArray = null;
try {
    splitArray = Regex.Split(subjectString, "<[^<>]*>");
} catch (ArgumentNullException ex) {
     // Cannot pass null as the regular expression or subject string
} 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("<[^<>]*>");
string[] splitArray = regexObj.Split(subjectString);

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

string[] splitArray = null;
try {
    Regex regexObj = new Regex("<[^<>]*>");
    try {
        splitArray = regexObj.Split(subjectString);
    } catch (ArgumentNullException ex) {
        // Cannot pass null as the subject string
    }
} 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 SplitArray = Regex.Split(SubjectString, "<[^<>]*>")

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

Dim SplitArray As String()
Try
    SplitArray = Regex.Split(SubjectString, "<[^<>]*>")
Catch ex As ArgumentNullException
    'Cannot pass null as the regular expression or subject string
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("<[^<>]*>")
Dim SplitArray = RegexObj.Split(SubjectString)

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

Dim SplitArray As String()
Try
    Dim RegexObj As New Regex("<[^<>]*>")
    Try
        SplitArray = RegexObj.Split(SubjectString)
    Catch ex As ArgumentNullException
        'Cannot pass null as the subject string
    End Try
Catch ex As ArgumentException
    'Syntax error in the regular expression
End Try

Java

You can call String.Split() directly when you want to split only one string with the same regular expression:

String[] splitArray = subjectString.split("<[^<>]*>");

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

try {
    String[] splitArray = subjectString.split("<[^<>]*>");
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

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

Pattern regex = Pattern.compile("<[^<>]*>");
String[] splitArray = regex.split(subjectString);

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

String[] splitArray = null;
try {
    Pattern regex = Pattern.compile("<[^<>]*>");
    splitArray = regex.split(subjectString);
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

JavaScript

The string.split() method can split a string using a regular expression:

result = subject.split(/<[^<>]*>/);

XRegExp

result = XRegExp.split(subject, /<[^<>]*>/);

PHP

$result = preg_split('/<[^<>]*>/', $subject);

Perl

@result = split(m/<[^<>]*>/, $subject);

Python

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

result = re.split("<[^<>]*>", subject))

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

reobj = re.compile("<[^<>]*>")
result = reobj.split(subject)

Ruby

result = subject.split(/<[^<>]*>/)

Discussion

Splitting a string using a regular expression essentially produces the opposite result of Recipe 3.10. Instead of retrieving a list with all the regex matches, you get a list of the text between the matches, including the text before the first and after the last match. The regex matches themselves are omitted from the output of the split function.

C# and VB.NET

In .NET, you will always use the Regex.Split() method to split a string with a regular expression. The first parameter expected by Split() is always the string that holds the original subject text you want to split. This parameter should not be null. If it is, Split() will throw an ArgumentNullException. The return value of Split() is always an array of strings.

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. You can pass regex options as an optional third 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 Split() on that object. The subject string is then the only required parameter.

When calling Split() on an instance of the Regex class, you can pass additional parameters to limit the split operation. If you omit these parameters, the string will be split at all matches of the regular expression in the subject string. The static overloads of Split() do not allow these additional parameters. They always split the whole string at all matches.

As the optional second parameter, after the subject string, you can pass the maximum number of split strings you want to end up with. For example, if you call regexObj.Split(subject, 3), you will receive an array with at most three strings in it. The Split() function will try to find two regex matches, and return an array with the text before the first match, the text between the two matches, and the text after the second match. Any further possible regex matches within the remainder of the subject string are ignored, and left in the last string in the array.

If there are not enough regex matches to reach your limit, Split() will split along all the available regex matches and return an array with fewer strings than you specified. regexObj.Split(subject, 1) does not split the string at all, returning an array with the original string as the only element. regexObj.Split(subject, 0) splits at all regex matches, just like Split() does when you omit the second parameter. Specifying a negative number will cause Split() to throw an ArgumentOutOfRangeException.

If you specify the second parameter with the maximum number of strings in the returned array, you also can specify an optional third parameter to indicate the character index at which the regular expression should begin to find matches. Essentially, the number you pass as the third 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 only want to split the remainder of the string.

The characters skipped by the regular expression will still be added to the returned array. The first string in the array is the whole substring before the first regex match found after the starting position you specified, including the characters before that starting position. If you specify the third parameter, it must be between zero and the length of the subject string. Otherwise, Split() throws an ArgumentOutOfRangeException. Unlike Match(), Split() does not allow you to specify a parameter that sets the length of the substring the regular expression is allowed to search through.

If a match occurs at the start of the subject string, the first string in the resulting array will be an empty string. When two regex matches can be found right next to each other in the subject string, with no text between them, an empty string will be added to the array. If a match occurs at the end of the subject string, the last element in the array will be an empty string.

Java

If you have only one string to split, you can call the split() method directly on your subject string. Pass the regular expression as the only parameter. This method simply calls Pattern.compile("regex").split(subjectString).

If you want to split multiple strings, use the Pattern.compile() factory to create a Pattern object. This way, your regular expression needs to be compiled only once. Then, call the split() method on your Pattern instance, and pass your subject string as the parameter. There’s no need to create a Matcher object. The Matcher class does not have a split() method at all.

Pattern.split() takes an optional second parameter, but String.split() does not. You can use the second parameter to pass the maximum number of split strings you want to end up with. For example, if you call Pattern.split(subject, 3), you will receive an array with at most three strings in it. The split() function will try to find two regex matches, and return an array with the text before the first match, the text between the two matches, and the text after the second match. Any further possible regex matches within the remainder of the subject string are ignored, and left in the last string in the array. If there are not enough regex matches to reach your limit, split() will split along all the available regex matches, and return an array with fewer strings than you specified. Pattern.split(subject, 1) does not split the string at all, returning an array with the original string as the only element.

If a match occurs at the start of the subject string, the first string in the resulting array will be an empty string. When two regex matches can be found right next to each other in the subject string, with no text between them, an empty string will be added to the array. If a match occurs at the end of the subject string, the last element in the array will be an empty string.

Java, however, will eliminate empty strings at the end of the array. If you want the empty strings to be included, pass a negative number as the second parameter to Pattern.split(). This tells Java to split the string as many times as possible, and leave any empty strings at the end of the array. The actual value of the second parameter makes no difference when it is negative. You cannot tell Java to split a string a certain number of times and also leave empty strings at the end of the array at the same time.

JavaScript

In JavaScript, call the split() method on the string you want to split. Pass the regular expression as the only parameter to get an array with the string split as many times as possible. You can pass an optional second parameter to specify the maximum number of strings you want to have in the returned array. This should be a positive number. If you pass zero, you get an empty array. If you omit the second parameter or pass a negative number, the string is split as many times as possible. Setting the /g flag for the regex (Recipe 3.4) makes no difference.

In a standards-compliant browser, the split() method includes the matches of capturing groups in the returned array. It even adds undefined for nonparticipating capturing groups. If you do not want these extra elements in your array, use only noncapturing groups (Recipe 2.9) in regular expressions you pass to split().

All the major web browsers now implement String.prototype.split() correctly. Older browsers have various issues with capturing groups and adjacent matches. If you want an implementation of String.prototype.split() that follows the standard and also works with all browsers, Steven Levithan has a solution for you at http://blog.stevenlevithan.com/archives/cross-browser-split.

XRegExp

When using XRegExp in JavaScript, call XRegExp.split(subject, regex) instead of subject.split(regex) for standards-compliant results in all browsers.

PHP

Call preg_split() to split a string into an array of strings along the regex matches. Pass the regular expression as the first parameter and the subject string as the second parameter. If you omit the second parameter, $_ is used as the subject string.

You can pass an optional third parameter to specify the maximum number of split strings you want to end up with. For example, if you call preg_split($regex, $subject, 3), you will receive an array with at most three strings in it. The preg_split() function will try to find two regex matches, and return an array with the text before the first match, the text between the two matches, and the text after the second match. Any further possible regex matches within the remainder of the subject string are ignored, and left in the last string in the array. If there are not enough regex matches to reach your limit, preg_split() will split along all the available regex matches and return an array with fewer strings than you specified. If you omit the third parameter or set it to -1, the string is split as many times as possible.

If a match occurs at the start of the subject string, the first string in the resulting array will be an empty string. When two regex matches can be found right next to each other in the subject string, with no text between them, an empty string will be added to the array. If a match occurs at the end of the subject string, the last element in the array will be an empty string. By default, preg_split() includes those empty strings in the array it returns. If you don’t want empty strings in the array, pass the constant PREG_SPLIT_NO_EMPTY as the fourth parameter.

Perl

Call the split() function to split a string into an array of strings along the regex matches. Pass a regular expression operator as the first parameter and the subject string as the second parameter.

You can pass an optional third parameter to specify the maximum number of split strings you want to end up with. For example, if you call split(/regex/, subject, 3), you will receive an array with at most three strings in it. The split() function will try to find two regex matches, and return an array with the text before the first match, the text between the two matches, and the text after the second match. Any further possible regex matches within the remainder of the subject string are ignored, and left in the last string in the array. If there are not enough regex matches to reach your limit, split() will split along all the available regex matches and return an array with fewer strings than you specified.

If you omit the third parameter, Perl will determine the appropriate limit. If you assign the result to an array variable, as the solution for this recipe does, the string is split as many times as possible. If you assign the result to a list of scalar variables, Perl sets the limit to the number of variables plus one. In other words, Perl will attempt to fill all the variables, and will discard the unsplit remainder. For example, ($one, $two, $three) = split(/,/) splits $_ with a limit of 4.

If a match occurs at the start of the subject string, the first string in the resulting array will be an empty string. When two regex matches can be found right next to each other in the subject string, with no text between them, an empty string will be added to the array. If a match occurs at the end of the subject string, the last element in the array will be an empty string.

Python

The split() function in the re module splits a string using a regular expression. Pass your regular expression as the first parameter and the subject string as the second parameter. The global split() function does not accept a parameter with regular expression options.

The re.split() function calls re.compile(), and then calls the split() method on the compiled regular expression object. This method has only one required parameter: the subject string.

Both forms of split() return a list with the text between all the regex matches. Both take one optional parameter that you can use to limit the number of times the string should be split. If you omit it or set it to zero, the string is split as many times as possible. If you pass a positive number, that is the maximum number of regex matches at which the string will be split. The resulting list will contain one more string than the count you specified. The last string is the unsplit remainder of the subject string after the last regex match. If fewer matches can be found than the count you specified, the string is split at all regex matches without error.

Ruby

Call the split() method on the subject string and pass your regular expression as the first parameter to divide the string into an array of strings along the regex matches.

The split() method takes an optional second parameter, which you can use to indicate the maximum number of split strings you want to end up with. For example, if you call subject.split(re, 3), you will receive an array with at most three strings in it. The split() function will try to find two regex matches, and return an array with the text before the first match, the text between the two matches, and the text after the second match. Any further possible regex matches within the remainder of the subject string are ignored, and left in the last string in the array. If there are not enough regex matches to reach your limit, split() will split along all the available regex matches, and return an array with fewer strings than you specified. split(re, 1) does not split the string at all, returning an array with the original string as the only element.

If a match occurs at the start of the subject string, the first string in the resulting array will be an empty string. When two regex matches can be found right next to each other in the subject string, with no text between them, an empty string will be added to the array. If a match occurs at the end of the subject string, the last element in the array will be an empty string.

Ruby, however, will eliminate empty strings at the end of the array. If you want the empty strings to be included, pass a negative number as the second parameter to split(). This tells Ruby to split the string as many times as possible and leave any empty strings at the end of the array. The actual value of the second parameter makes no difference when it is negative. You cannot tell Ruby to split a string a certain number of times and also leave empty strings at the end of the array at the same time.

See Also

Recipe 3.20 shows code that splits a string into an array and also adds the regex matches to the array.

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

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