ES2018 - New RegEx flag
For those of you who don’t know, or perhaps don’t remember, we use RegEx in order to perform various operations on text. An example would be to check if a particular string meets certain conditions that we can set. Say for instance, we want to verify that a certain text contains only letters and not numbers, we can do something like this:
let text = 'someUserName'; /^[A-Za-z]*$/.test(text);// true text = "' or 68 = '66; DROP ALL TABLES; --';"; /^[A-Za-z]*$/.test(text);// false
For each regular expression there are also flags.
Flags are used for changing the behavior of the RegEx itself. For instance, in the example there is a RegEx that contains A-Z and a-z—in order to have all letters, both capital and lowercase, in the criteria. If I use flag i, I can say that if I use a-z it’s like using A-Z and the opposite as well. In other words, it doesn’t matter if the letters are upper or lowercase—it’s now case-insensitive.
let text = 'someUserName'; /^[A-Z]*$/i.test(text);// true text = "someUserName"; /^[A-Z]*$/.test(text);// false
In the first RegEx, I’m using flag i. This means the RegEx A-Z now includes both upper and lowercase letters, it will return true on the text string ‘userName’, which contains both upper and lowercase letters. In the second RegEx I’m not using flag i (notice there is no \i there). So now the same text string will return false because the expression says that only uppercase letters meet the criteria.
It says, there can be one character, and it doesn’t matter what type. It’s supposed to catch any character: English letters, letters in Hebrew or Arabic. So when does it fail? Only on an empty string:
let text = 'a'; /^.$/.test(text);// true text = 'ג'; /^.$/.test(text);// true text = 'ض'; /^.$/.test(text);// true text = ''; /^.$/.test(text);// false text = 'cd'; /^.$/.test(text);// false
You can easily see that as long as I’m passing one character, and only one character, the expression works. And if I pass an empty string or more than one character? Bam! We get false.
So what’s the issue then? The problem starts if I check for a new line. Shouldn’t be a problem. New line is considered to be one character. Logic says yes, but if we test it:
text = '\n'; /^.$/.test(text);// false
Before, there were all kinds of tricks and gimmicks to get around this, which was really too bad. But in ES2018, they’ve added a new flag, flag s, which says the dot (which is what’s supposed to match all characters) will include line terminator characters, like \n. So now:
text = '\n'; /^.$/s.test(text) // true
Notice the \s. So from now on, if you write a RegEx, remember to put in the flag s if you’re using a dot (all characters) and you want to catch line breaks. And if you don’t ever write RegEx? Well hey, at least you learned something new.
About the author: Ran Bar-Zik is an experienced web developer whose personal blog, Internet Israel, features articles and guides on Node.js, MongoDB, Git, SASS, jQuery, HTML 5, MySQL, and more. Translation of the original article by Aaron Raizen.