I don’t know if you have an inexplicable and wonderful fear of regex like me. When you encounter regular matching in daily development, you find it hard to find it through Baidu and Google. However, when the interviewer asks this question in the interview, you begin to regret why you were not so eager to learn at the beginning. This is also in the process of preparing for the interview is the most easy to ignore a knowledge point, so the success rate of the interview is very low, today, let us to overcome the fear of the heart, to see the written interview, the interviewer can put the regular ask what flower!

The RegExp object

Regexp is a built-in JS object used for regular matching. There are two ways to instantiate a RegExp object:

Literal:

const reg = /hello/
const a = 'helloworld'.replace(reg,'HELLO')  // HELLOworld 

The constructor

const reg = new RegExp('hello')
const a = 'helloworld'.replace(reg,'HELLO')   //HELLOworld

Use the replace method, if the second parameter string is replaced, that means the match, and the front-end daily development is often used to replace the regular matching character operation, regular more with the example dozen, you will become more and more skilled!

The modifier

I performs a case-insensitive match.

G performs global matching (looking for all matches rather than stopping when the first match is found).

M performs multi-line matching.

Such as:

const reg = /hello/g const a = 'helloworldhello'.replace(reg,'HELLO') // HELLOworldHELLO const reg1 = /hello/i const b =  'hellOworld'.replace(reg1,'HELLO') // HELLOworld

metacharacters

Regular expressions consist of two basic character types

  • The literal text characters a,b,c… (represents the meaning of the letter itself, such as hello in the example above, which means to match hello in the string, but nothing else.)
  • Metacharacter A character that has a special meaning

The simplest regular expressions are alphanumeric, as in the example above, but as we know, it’s often not that simple.

Take a look at this question:

Const reg = d / \ \ B \ d {2} {2} \ \ w w \ \ s \ s = '1 B/const a_a (& s'. The replace (reg,' match)

Can n you tell the result of the above expression? Can’t tell? It doesn’t matter. Let’s talk it out.

A single character

In addition to letters and numbers, when we want to match a special character, we have to invoke our first metacharacter \, which is an escape character that, as the name implies, makes subsequent characters lose their original meaning. Here’s an example:

I want to match the * symbol, and since the * symbol itself is a special character, I want to make it lose its original meaning by escaping the metacharacter \ :

So, using /*/ simply matches the * character

const reg = /\*/g 
const a = '*world*'.replace(reg,'HELLO')  //HELLOworldHELLO

If the character is not a special character, using an escape gives it a special meaning. We often need to match special characters, such as Spaces, tabs, carriage returns, line feeds, etc., and these need to be matched using escape characters. This needs us to remember! Remember the escape symbol \, don’t remember it backwards!

Character classes and scope classes

So if I want to match any of the characters in 123, then I need to use brackets [and], and in regular expressions, collections are defined using brackets [and]. The /[123]/ regular matches 1,2, and 3 characters at the same time.

const reg = /[123]/
const a = '1'.replace(reg,'HELLO')  //HELLO
const b = '2'.replace(reg,'HELLO')  //HELLO

What if I want to match all the numbers? Going from 0 to 9 is obviously too inefficient, so the metacharacter – can be used to indicate the range, and /[0-9]/ matches all numbers, and /[a-z]/ matches all lowercase English letters. Note that regular expressions are strictly case sensitive.

const reg = /[0-9]/ const reg1 = /[a-z]/ const a = '8'.replace(reg,'HELLO') //HELLO const b = 't'.replace(reg1,'HELLO') //HELLO const c = 'T'.replace(reg1,'HELLO') //T, replace does not replace because it does not match

What if we just want to match numbers and -? It is simple to escape with \ – to make him lose his own special meaning

const reg = /[0-9|\-]/g
const d = '2020-01'.replace(reg,'H') //HHHHHHH

Have you failed your studies?

Instead of defining the range of characters to match in a collection using -, we have an easier way to use metacharacters in regular expressions.

Common metacharacters are defined as follows:

Thank you for digging friend @ scq000 provide memory map The article portal: https://juejin.cn/post/684490…

The following example does not have a global match. The match stops when it reaches the first match

const reg = /\d/
const a = '8'.replace(reg,'HELLO')  //HELLO 
const reg1 = /\D/
const b = '8'.replace(reg1,'HELLO')  //8   
const reg2 = /\w/
const c = 't'.replace(reg2,'HELLO') //HELLO
const reg3 = /\W/
const d = 't'.replace(reg3,'HELLO') //t

quantifiers

Now, if we want to match a string with a number that appears 10 times in a row, we can use

const reg = /\d\d\d\d\d\d\d\d\d\d/

What if the match happens 10,000 times? Wouldn’t it be a good idea to write a regular expression quantifier?

Thank you for digging friend @ scq000 provide memory map The article portal: https://juejin.cn/post/684490…

So according to the definition of these quantifiers, let’s actually see how to use them.

const reg = /\d{3}/ const a = '1234'.replace(reg,'HELLO') //HELLO4 const reg1 = /\D? / const b = '8'.replace(reg1,'HELLO') //HELLO8 const c = 'w'.replace(reg1,'HELLO') //HELLO const reg2 = /\d*/ const d = '77782837464838'.replace(reg2,'HELLO') //HELLO const e = 'w'.replace(reg2,'HELLO') //HELLOw const reg3 = /\d+/ const f =  '77782837464838'.replace(reg3,'HELLO') //HELLO const g = 'w'.replace(reg3,'HELLO') //w

The border

So if we have a string, ‘This is a student’ and we want to match all the iss in the string, then if we use /is/ you can see that the iss in This is also matched

const reg = /is/g
const a = 'This is a student'.replace(reg,'HELLO') //ThHELLO HELLO a student

At this time we need the boundary character to appear, the common boundary character

So for example, if we want to match “is”, the “is” will be the word’s boundary, so

const reg = /\bis\b/g
const a = 'This is a student'.replace(reg,'HELLO') //This HELLO a student

What if we want to match is in This?

const reg = /\Bis\b/g
const a = 'This is a student'.replace(reg,'HELLO') //ThHELLO is  a student

So you can understand “b” and “b” to limit whether the matching character is at the edge of our word.

If we have a string like thisisTheBest, and we only want to match the th in this, you can qualify the matching character with the ^ which isthe beginning of the whole string

const reg = /^th/
const a = 'thisisthebest'.replace(reg,'HELLO') //HELLOisisthebest

Similarly, $qualifies the matching character at the end of the string

const reg = /test$/
const a = 'testisatest'.replace(reg,'HELLO') //testisaHELLO

const reg2 = /^test./
const b = 'testisatest'.replace(reg2,'HELLO') //HELLOsatest

Finally, look at our example above:

Const reg = d / \ \ B \ d {2} {2} \ \ w w \ \ s \ s = '1 B/const a_a (& s'. The replace (reg,' match)

The above regular expression translates to a number with a non-word boundary with a number with a letter with two non-letters with two white space characters with a non-white space character with a word boundary

The result is a match

subexpression

So we have probably learned the most basic regular, do you need to come to some interview questions open appetizer? Write a regular expression that matches the following three date formats:

The 2016-06-12 2016/06/12 2016.06.12

At this point someone might have written a regular that looks like this

const reg = /\d{4}[\-\/\.]\d{2}[\-\/\.]\d{2}/

I’m sorry to tell you that the answer is wrong.

const reg = /\d{4}[\-\/\.]\d{2}[\-\/\.]\d{2}/
const a = '2020-02-02'.replace(reg,true)  //true
const b = '2020-02/02'.replace(reg,true)  //true

The problem clearly requires that there should be a uniform separator character, so it does not meet the requirements of the problem. To have uniform delimiter characters, a mechanism is required to capture the first delimiter and keep the second delimiter consistent with it. This is where you need to backreference.

grouping

The function of grouping can be achieved by using (), so that the quantifier is applied to the grouping. The expressions contained in () can be considered as a group, for example:

const reg = /(is){3}/g
const a = 'isisisis'.replace(reg,true)  //trueis

If grouping is used only for matching, that’s only about 10 percent of its function, and much more for backreferencing.

backreferences

Back to our topic, match the date string such as 2016-06-12, 2016-06/12, there is a hidden condition that the delimiter between my month and the day must be the same as the first delimiter, otherwise the string such as 2016-02/09 will also be matched. This is the time to use a backreference, which is to refer to a substring that has already been matched at the end of our regular string. You can think of it as a variable with a backreference syntax like \1,\2,…. , where \1 represents the first subexpression of the reference (matched to the first grouping), \2 represents the second subexpression of the reference (matched to the second grouping), and so on. And \0 represents the entire expression.

So the regular expression matching 2016-06-12, 2016/06/12, 2016.06.12 can be written as:

| or said, means to match one of them

/\d{4}(-|\/|\.) \d{2}\1\d{2}/

Remember, the premise of a backreference is to group with () first

A lot of times, grouping and backreferencing are also used in string substitutions, where $1,$2… To replace the matched expression

For example, if we need to convert a format like 2020-02-10 to a format like 10/02/2020, we could write 👇

const reg = /(\d{4})-(\d{2})-(\d{2})/g
const a = '2020-02-10'.replace(reg,'$3/$2/$1')  //10/02/2020

Let’s do another similar problem

Write a function that converts the hump-type string to a -concatenated string, such as getElementById — -> GET-ELEMENT-BY-ID

Think about it for a minute before you see the answer!!

function convert(str){
    const reg = /([A-Z])/g
    return str.replace(reg,'-$1').toLowerCase() 
}


convert('getElementById')  //get-element-by-id

Write a function that converts the -concatenated string to a string of type hump, such as GET-ELEMENT-BY-ID -> getElementByID

Think about it for a minute before you see the answer!!

function conversion(str) { 
  return str.replace(/-(\w{1})/g, ($1,$2)=>
       $2.toUpperCase()
  )
}
conversion('this-is-good')

Start with a regular expression to determine the phone number

Think about it for a minute before you see the answer!!

const reg = /^1[34578]\d{9}$/

foresight

There’s a scene “HappyHappily” where I want to match the adverb “HappyHappily” where I can use foresight to satisfy my need

const reg = /happ(? =ily)/ const a = 'happyhappily'.replace(reg,'HELLO') //'happyHELLOily' const reg2 = /\d+(? =%)/ const b = '50%'.replace(reg2,'XX') //XX%

A regular expression starts parsing from the head of the text to the end, in the direction of the end of the text, known as the ‘front’.

When a regular expression matches a rule, it checks the end of the text to see if it matches the assertion. The assertion part is not counted in the matching character.

Can’t read it? That’s all right. Let’s take a look at this question, which is also a common interview question:

How do I add a thousandth separator to a number?

There’s a toLocaleString method that has nothing to do with regularization, so you can look at it, and let’s see how to do it with regularization.

vartoThousands = function(number) { return (number + '').replace(/(\d)(? =(\d{3})+$)/g, '$1,'); } vartoThousands(123456789)

According to the foresight, /(\d)(? =(\d{3})+)/ is the string that matches the number on the left with more than a multiple of 3 on the right, but we find that it replaces 11231234 with 1,1231234.

That’s obviously not what we want, we just want the right-hand side to be exactly a multiple of 3, so we add $ , & dollar; The last character that matches the foresight assertion must be the end of the string, which means that 11231234 matches from the top of the string. When we evaluate a 1, we find that there are 3×2 digits following it, but it is not the end of the string, so we continue to match the next 1, which has 3×2 digits following it. And is the end of the string, so use /(\d)(? =(\d{3})+$) /, this is going to replace 11231234 with 11,231234, which is going to get us closer to where we want to be than we did in the last step, but we’re not done with the right-hand side. So let’s continue matching 231234 on the right with the same matching rule. Add the g modifier, and you have /(\d)(? =(\d{3})+$)/g, and this is what we want.

Does that make sense?

The interview questions,

Verify ID card number

The rule ID number may be 15 or 18 digits, 15 digits are all digits, the first 17 digits of 18 digits are digits, and the last digit is either a number or an X

function isCardNo(number) {
    var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    return regx.test(number);
}

Adds a prototype method called trim to JavaScript’s string native that truncates white space characters before and after a string

String.prototype.trim = function(){
    return this.replace(/^\s*|\s*$/g,'');
} 
console.log('  love  love    '.trim())   //love  love

The url of the params

Gets the parameters in the URL

Specifies a parameter name, returns the value of the parameter or an empty string with no parameter name, returns all parameter objects or {}, returns an array if more than one parameter has the same name

function getUrlParam(url, key) { var arr = {}; url.replace(/\?? (\w+)=(\w+)&? /g, function(match, matchKey, matchValue) { if (! arr[matchKey]) { arr[matchKey] = matchValue; } else { var temp = arr[matchKey]; arr[matchKey] = [].concat(temp, matchValue); }}); if (! key) { return arr; } else { for (ele in arr) { if (ele = key) { return arr[ele]; } } return ''; }}

Replace the blank space

From leetcode: https://leetcode-cn.com/probl…

Implement a function that replaces each space in the string S with “%20”.

Input: s = "We are happy." Output: "We%20are%20happy."

You can just go to leetcode and write down your code verification!

/** * @param {string} s * @return {string} */ var replaceSpace = function(s) {// replaceSpace = function(s). Return s.replace(/\s/g,'%20')}; return s.replace(/\s/g,'%20');

Verify that it is an email address

Rule definition:

• In capital letters [a-z], lowercase letters [a-z], numbers [0-9], glide lines _, minus signs – and dots. And need to repeat once or more +.

• Must include the @ sign.

• The @ should be followed by A capital letter [a-z], A lowercase letter [a-z], A number [0-9], A glide line _, A minus sign -, and A dot., and the + should be repeated once or more.

• Must end with a dot. Connect 廏 to the upper and lower case letter [a-za-z]{2,4} of the bit bit.

Var pattern = / ^ ([A Za - z0-9 _ \ - \]) + \ @ ([A - Za - z0-9 _ \ - \]) + \. ([A Za - z] {2, 4}) $/; pattern.test('[email protected]') //true; pattern.test('[email protected]') // true; pattern.test('[email protected]') // true; pattern.test('[email protected]') // true; pattern.test('[email protected]') // false; Pattern. Test (' [email protected] ') // false;

Fill the function code to make it fully functional

Var STR = "Hello, <%=name%>. Welcome to <%=location%>"; function template(str) { // your code } var compiled = template(str); // Compiled output value is: "Hello, Zhang San. Welcome to Compiled ({name: "three ", location:" XXX "});

Think about it for a minute before looking at the answer

Var STR = "Hello, <%=name%>. Welcome to <%=location%>"; function template(str) { return data => str.replace(/<%=(\w+)%>/g, (match, p) => data[p] || '') } var compiled = template(str); Compiled ({name: "XXX ", location:" XXX "}); // Compiled output value is: "Hello, Zhang San. Welcome to XXX"

Implement a render(template, context) method that fills the placeholder in the template with the context.

Example:

Var context = {name:"bottle",age:"15"} input: template context output: bottle = "{{name}}" Cascaded variables can also be expanded to allow white space characters between delimiters and variables

When a regular expression contains qualifiers that accept repetition, the usual behavior is to match as many characters as possible (without making the entire expression a match).

Take this expression: a.*b, which will match the longest string that starts with a and ends with b.

If you use it to search for aabab, it will match the entire string aabab. This is called greedy matching

If this is the case, we will get {{name}} and {{age}}, which is not what we want

We need the {{name}} and {{age} sections, so non-greedy matches to match all {{}} templates

This means using.*? To make a match

const render = (template, context) => { const reg = /{{(.*?) }} / g return template. Replace (reg, (match, p) = > {return context [p.t rim ()] | | '})} render (" {{name}}, Only {{age}} age ", {name: "bottle", age: "15"})

Of course, we don’t have to write a non-greedy match

const convertTemplate = (template, context) => { const reg = /{{\s*(\w+)\s*}}/g return template.replace(reg, (match, P) = > {return context [p] | | '})} convertTemplate (" {{name}}, {{age}}, only ", {name: "bottle", the age: "15"})

Refer to the article

https://juejin.cn/post/684490…

https://juejin.cn/post/684490…

https://juejin.cn/post/684490…