Recipe 9.5 Extracting a Substring

9.5.1 Problem

You want to extract a substring from a string.

9.5.2 Solution

Use the substring( ), substr( ), or slice( ) methods.

9.5.3 Discussion

The substring( ), substr( ), and slice( ) methods all return the value of a substring without affecting the original string. The only difference between the three methods is in the parameters they accept.

The substr( ) method takes up to two parameters:

startIndex

The position of the first character of the substring. The value can be negative, in which case the index is calculated from the end of the string, where -1 is the last character, -2 is the second-to-last character, and so on.

length

The number of characters in the substring to extract. If this parameter is omitted, all the characters from startIndex to the end are used:

myString = "Bunnies";
trace(myString.substr(0));      // Displays: Bunnies
trace(myString.substr(0, 3));   // Displays: Bun
trace(myString.substr(3, 3));   // Displays: nie
trace(myString.substr(-1));     // Displays: s
trace(myString.substr(-2, 5));  // Displays: es

The substring( ) and slice( ) methods each take the same parameters:

startIndex

The position of the first character of the substring to extract.

endIndex

The position of one character after the last character in the substring to extract. If this parameter is omitted, all the characters from the startIndex to the end are used.

The substring( ) and slice( ) methods differ in that substring( ) accepts positive index values only; it interprets negative values as 0. Also, if endIndex is less than startIndex, the substring( ) method automatically reverses them before executing. The slice( ) method, on the other hand, accepts negative values for both startIndex and endIndex; it interprets negative values as counting back from the end of the string. The slice( ) method fails if you specify an endIndex that is less than startIndex.

myString = "Rabbits";

// Both of these output the entire string, beginning at index 0 and going to the last
// index (the value of which is myString.length - 1).
trace(myString.substring(0));       // Displays: Rabbits
trace(myString.slice(0));           // Displays: Rabbits

// The substring(  ) method outputs nothing because it converts the negative indexes to
// 0. The slice(  ) method outputs "it", which is the substring from the third-to-last
// character (index -3) to the next-to-last character (index -1).
trace(myString.substring(-3, -1));  // Displays nothing
trace(myString.slice(-3, -1));      // Displays: it

// Both of these output the substring "ab".
trace(myString.substring(1, 3));    // Displays: ab
trace(myString.slice(1, 3));        // Displays: ab

// The substring(  ) method outputs the substring "ab" because it reverses the order of
// the parameters automatically. The slice(  ) method outputs nothing because the
// slice(  ) method does not reverse the order of the parameters.
trace(myString.substring(3, 1));    // Displays: ab
trace(myString.slice(3, 1));        // Displays nothing

You will commonly use the substring-extraction methods in conjunction with the indexOf( ) and lastIndexOf( ) methods. You can use the indexOf( ) and lastIndexOf( ) methods to search for the substring within a string, and then you can use the substring-extraction methods to get the substrings.

This example extracts a file's extension and its filename (without the extension), which are presumed to be separated from each other by a period:

filename = "mydocument.jpg";
// Find the location of the period.
extIndex = filename.lastIndexOf(".");

// The extensionless filename ("mydocument") is everything before the period.
strippedFileName = filename.substr(0, extIndex); 
trace ("The filename is " + strippedFileName);

// The extension ("jpg") is everything after the period.
extension = filename.substr(extIndex + 1, filename.length);
trace ("The file extension is " + extension);

You can also use the split( ) method, assuming there is only one period in the filename:

filename = "mydocument.jpg";
// Split the string wherever the period occurs.
nameArray = filename.split(".");

// The first element is "mydocument" (everything before the first period).
strippedFileName = nameArray[0];
trace ("The filename is " + strippedFileName);

// The next element is "jpg" (anything after the first 
// period and before the next one).
extension = nameArray[1];
trace ("The file extension is " + extension);

Compare the two preceding examples. What happens if the filename contains no periods, such as "mydocument"? (Hint: The first example fails in that case.) What if the filename contains more than one period, such as "ascb_fig8.1.bmp"? (Hint: The second example fails in that case.)

Here is a general solution:

// This function returns everything before the last period, if any.
function stripExtension (filename) {
  // Find the location of the period.
  extIndex = filename.lastIndexOf(".");
  if (extIndex == -1) {
    // Oops, there is no period. Just return the filename.
    return filename;
  } else {
    return filename.substr(0, extIndex);
  } 
}

// This function returns everything after the last period, if any.
function extractExtension (filename) {
  // Find the location of the period.
  extIndex = filename.lastIndexOf(".");
  if (extIndex == -1) {
    // Oops, there is no period, so return the empty string
    return "";
  } else {
    return filename.substr(extIndex + 1, filename.length);
  } 
}
// Example usage:
trace(stripExtension("mydocument.jpg"));       // Displays: mydocument
trace(stripExtension("mydocument"));           // Displays: mydocument
trace(stripExtension("mydocument.1.jpg"));     // Displays: mydocument.1
trace(extractExtension("mydocument.jpg"));     // Displays: jpg
trace(extractExtension("mydocument"));         // Displays nothing
trace(extractExtension("mydocument.1.jpg"));   // Displays: jpg

9.5.4 See Also

Recipe 9.8



    Part I: Local Recipes
    Part II: Remote Recipes