Somewhere, in all of your past googling of prime number algorithms, you might have come across something like this:

What’s this? It’s a way of checking to see if a number is prime! And you don’t even have to write a for loop!

Pretty wild, right?

I thought so too. So I figured it might be fun to break this regular expression down and explain it step-by-step in case anyone was curious.

Note: I know regular expressions (the stuff between the /’s) can look like magic but stick with me and I promise it will all make sense.

Okay so what is happening?

So basically this function is following three steps:

turn the number into its unary form check to see if it is a 0 or a 1 check to see if it is a multiple of any number larger than 1

Step 1

So first we are going to turn the number we are checking into its unary form. “Unary” is basically a fancy way of saying tally marks (i.e. 3 becomes “111”, 4 becomes “1111”, etc.).

That is achieved by this piece of code:

This is basically saying, “create an Array with n + 1 empty slots, and join all of those empty values with 1's.”

I prefer using the String.prototype.repeat() method from ES6, which looks like this:

Doing it this way saves you from first having to create an array and then joining all of its elements into a string. It’s also much more intuitive to read, but the older way of doing it is all over the internet, so I thought I would show both.

Great! Moving on!

Step 2

So now we are going to start seeing if this unary version of our number matches the regular expression. The regex can be broken down into two parts, everything to the left of the | (which works like an OR operator) and everything to the right of it.

The left side would be:

So let’s go character by character through this.

First, the ^ .

That tells the regular expression that it needs to match the beginning of the string, so it can’t find patterns that start in the middle, end, or anywhere else but the beginning. This guy is the counterpart to the $ which tells our regex where the end of the string must be. Basically, this is saying that the entire string must match the regex and there can’t be any remainder left over.

Next we have the 1 .

Here, the 1 is just saying to find the character “1” in the string. We could have made a unary string of all 2’s (i.e. 3 becomes “222” etc.) and this character would need to be a 2. It just needs to be the same as whatever character you used to make your string.

Next is the ? .

This is saying that the character before it is optional, so the regex will match zero “1”s or one “1” (i.e. “” or “1”).

The last character is the $ .

Like I said, it’s the counterpart to ^ . This is how we know there is no remainder at the end!

So this part of our regex accomplishes step 2, checking to see if the number passed in was a 0 or a 1.

Great! Next!

Step 3

This is where the fun starts. Now we need to see if the number is a multiple of anything larger than 1. If it is, then it is not a prime number! So let’s take a look at the right side of our regex:

Here we have the same ^...$ pattern as before, saying that the string has to start and end in those places for the match to work. So first let’s look at what the parentheses are doing.

(11+?)

The parentheses here are creating a grouping, which is important because we are checking for multiples. If we want to see that our number is not a multiple of 2, we are going to need to group all of the “1”s into “11”s and find out if there is a remainder.

The first two 1 ‘s inside the parentheses are the same as the 1 ‘s from before. They are simply matching the “1”s in the unary string version of the number.

The + says to match one or more of the character that precedes it. So there needs to be at least two “1”s for there to be a match, but any number of “1”s larger than that will also match.

The ? after the + is super important. It makes the + “non-greedy.” That means that it will match the smallest part of the string possible first. It will start by only matching two “1”s, then three “1”s, then four and so on. If the ? were missing, then the + would be greedy, and match as much of the string as it possibly could, which for us is the entire string since our string only contains one character.

So now that we have our grouping of two or more “1”s, we need check to see if multiples of our grouping will match the rest of the string with no remainder (i.e. until the very end of the string). That’s where this comes in:

\1+?

So the first bit of this is \1 which is called a back-reference. It will reference whatever the first grouping was in our regex. Think of it like a regex variable. It refers to the stuff between those parentheses.

The +? after it should look familiar. This is non-greedily checking that there could be one or more iterations of our back-reference.

So if (11+?) matches the string “11”, our back-reference will also match “11”, so our regex is looking for anything that is a multiple of “11”, starting with “1111”, then “111111”, etc. If that fails (if our number is odd), then it will go back and add another “1” to the bit inside the parentheses and try to match anything that is a multiple of “111”.

If our regex ever returns true for a match, that means that our number is 1) a 0 or a 1, or 2) a multiple of a number larger than 1. That means that it is not (i.e. ! ) prime! Cool, right?

Take a look at that code one more time to see that you understand all of it:

And here you can see a version with some nice ES6 syntax that removes the need to create an unnecessary array:

That’s all I have for now. Thanks for reading! Hope you enjoyed yourself and feel ready to do some regex magic on your own.