JavaScript Regex Returning True.. Then False.. Then True.. etc

Javascript regex returning true.. then false.. then true.. etc

/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;

You're using a g (global) RegExp. In JavaScript, global regexen have state: you call them (with exec, test etc.) the first time, you get the first match in a given string. Call them again and you get the next match, and so on until you get no match and it resets to the start of the next string. You can also write regex.lastIndex= 0 to reset this state.

(This is of course an absolutely terrible piece of design, guaranteed to confuse and cause weird errors. Welcome to JavaScript!)

You can omit the g from your RegExp, since you're only testing for one match.

Also, I don't think you want [^-_] at the front and back. That will allow any character at each end, ie. *plop! would be valid. You're probably thinking of lookahead/lookbehind assertions, but they're not available in JavaScript. (Well, lookahead is supposed to be, but it's broken in IE.) Suggest instead:

/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i

regex that returns false and true

"As with exec (or in combination with it), test called multiple times on the same global regular expression instance will advance past the previous match." https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test

You can work around this behavior by either resetting the lastIndex to 0 or creating a new regex each test.

why does my javascript regex.test() give alternating results

When you're using /g, the regex object will save state between calls (since you should be using it to match over multiple calls). It matches once, but subsequent calls start from after the original match.

(This is a duplicate of Javascript regex returning true.. then false.. then true.. etc)

RegExp.Test always returning false

Your syntax is wrong.

Change it to var expression = /^[0-9a-z_]+$/i;

Unlike PHP, Javascript supports regex literals the syntax /.../ creates a RegExp object.

The RegExp constructor takes a regex as a string, without separators.

Therefore, you could also write new RegExp('^[0-9a-z_]+$', 'i')

JS Regex returning -1 & 0

if(vowels.test(s[i])){ which will return true or false if it matches, or

if(s[i].search(vowels) !== -1){ and if(s[i].search(vowels) === -1){
is what you want if you want to fix your code.

-1 is not falsey so your if statement will not function correctly. -1 is what search returns if it doesn't find a match. It has to do this because search() returns the index position of the match, and the index could be anywhere from 0 to Infinity, so only negative numbers are available to indicate non-existent index:

MDN search() reference

Below is a RegEx that matches vowel OR any letter OR other, effectively separating out vowel, consonant, everything else into 3 capture groups. This makes it so you don't need to test character by character and separate them out manually.

Then iterates and pushes them into their respective arrays with a for-of loop.

const consonants = [], vowels = [], other = [];
const str = ";bat cat set rat. let ut cut mut,";
for(const [,cons,vow,etc] of str.matchAll(/([aeiouAEIOU])|([a-zA-Z])|(.)/g)) cons&&consonants.push(cons) || vow&&vowels.push(vow) || typeof etc === 'string'&&other.push(etc)
console.log(consonants.join('') + '\n' + vowels.join('') + '\n' + other.join(''))

Why the results from running exactly the same regular expression twice are different?

That's because the search starts from the previous match for each invocation of test:

test called multiple times on the same global regular expression instance will advance past the previous match.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

Why is test() returning True when it should fail?

Try this:

console.log(/^[A-Za-z0-9-_:]+$/.test('zoom^Bar'))

Bug with RegExp in JavaScript when do global search

The reason for this behavior is that RegEx isn't stateless. Your second test will continue to look for the next match in the string, and reports that it doesn't find any more. Further searches starts from the beginning, as lastIndex is reset when no match is found:

var pattern = /te/gi;

pattern.test('test');
>> true
pattern.lastIndex;
>> 2

pattern.test('test');
>> false
pattern.lastIndex;
>> 0

You'll notice how this changes when there are two matches, for instance:

var pattern = /t/gi;

pattern.test('test');
>> true
pattern.lastIndex;
>> 1

pattern.test('test');
>> true
pattern.lastIndex;
>> 4

pattern.test('test');
>> false
pattern.lastIndex;
>> 0


Related Topics



Leave a reply



Submit