Here’s something I learned re-learned recently: you can pass negative values into the left() and right() functions in CFML. Thanks to John Whish for pointing this out in a pull request on cfdocs.org.

The left() and right() functions work great for grabbing the beginning or ending of a string respectively, but with negative values you can remove the end or beginning of a string.

It is a little bit backwards to think about, so here’s an example. Suppose you have a string:

s = "(bingo)";

Your task is to remove the first and last characters (the parenthesis). Without using negative values you could remove the first parenthesis by using right:

right(s, len(s)-1); //returns bingo)

To remove the first character using a negative value, you can instead just use a negative value:

right(s,-1); //returns bingo)

Or if you prefer the member function syntax:

s.right(-1); //returns bingo)

To remove the last character you could similarly use a positive count, like this: left(s, len(s)-1) or simply use the negative value:

left(s, -1); //returns (bingo
s.left(-1); //returns (bingo

Here’s a trycf code sample you can try the above examples for yourself.

Negative value larger than the string length

What happens when you pass a negative value that is larger than the length of the of the string, so for example if we pass:

left(s, -10); //returns (bingo)

It returns the full string on both Lucee and Adobe ColdFusion.

Compatibility

This feature was added to ColdFusion 2018, versions before that will throw an exception if you pass a negative value in the second argument of the left or right functions.

It also works on Lucee going back as far as version 4.5.

Beware of the implications

This new feature could cause issues in sloppy code, which would have thrown an exception previously, not might cause a totally different behavior.

Let’s suppose I had some code meant to strip out a leading "https://" on a website variable:

website = right(website, len(website)-8);

Now what happens when the website variable is set to "abc.com" without a "https://" prefix. Instead of throwing an exception here, modern versions of CF would simply return "bc.com". It’s kind of an odd example, but it was the best I could think of, hopefully you can see how it could make a difference in some cases.

Typically when you use the left or right functions with a variable count, you should check the length of the string first, for example:

if ( len(website) > 8 ) {
    //strip https://
    website = right(website, len(website)-8);
}

As long as you are doing that kind of check, you should not have any issue with unexpected change of behavior due to this change.

Zero Still Throws Exception

Passing a zero to the second argument of left or right still throws an exception on both Lucee and ColdFusion:

The value of parameter 2 of the function Right, which is now 0, must be a non-zero integer on line 1

Left and Right Accept Negative Counts was first published on May 02, 2024.

Similar Posts