I do not know whether we are like me, there is a strange fear of regular, daily development to regular matching, Baidu Google a shuttle ha, but when the interview when the interviewer asked this question, the in the mind began to regret why it was not good to learn. This is also the most easy to ignore in the process of preparing for the interview, so the success rate of the interview is very low, today, let us overcome the inner fear, look at the written interview, the interviewer can ask the re out of what flower!

The RegExp object

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

Literal:

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

The constructor

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

If the replace method is replaced by the second parameter string, it indicates that the match is made, and the front-end daily development is a lot of time to use the replace to the regular matching character operation, the regular more with the example dozen, will become more and more skilled!

The modifier

I Performs case-insensitive matching.

G performs global matching (finds all matches instead of stopping after finding the first match).

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') // HELLOworldCopy the code

metacharacters

Regular expressions consist of two basic character types

  • Literal text characters A, B, C… (Represents the meaning of the letter itself. For example, hello in the example above refers to the matching of hello in the string. There is no other special meaning.)

  • Metacharacters characters with special meanings

The simplest regular expressions are alphanumeric, like the one 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)Copy the code

Can n you tell the result of the expression above? Can’t tell? That’s okay. Let’s talk about it.

A single character

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

I want to match the symbol *, which is itself a special character, so I use the escape metacharacter \ to make it lose its original meaning:

So, using /*/ simply matches the * character

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

If the character is not a special character, using an escape symbol gives it a special meaning. We often need to match special characters, such as Spaces, tabs, carriage returns, newlines, etc., which we need to use escape characters to match. This needs us to remember! The way to remember escape symbols is \, don’t remember them backwards!

Character classes and scope classes

If I want to match any of the characters of 123, THEN I need to use brackets [and]. In regular expressions, collections are defined by brackets [and]. For example, /[123]/ 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
Copy the code

So what if I want to match all the numbers? Writing from 0 to 9 is obviously too inefficient, so the metacharacter – can be used to indicate ranges, /[0-9]/ will match all numbers, and /[a-z]/ will match all lowercase 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') Replace (reg1,'HELLO') // const c = 'T'. Replace (reg1,'HELLO') //Copy the code

So what if we just want to match numbers with –? Very simple, use \ to escape – make him lose his own special meaning

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

Have you failed your study?

Instead of using – to define the range of characters to match in collections, there is an easier way to use metacharacters in regular expressions.

Common metacharacters are defined as follows:

Thanks to digger @scq000 for providing the memory map article portal: juejin.cn/post/684490…

The following example does not have a global match, and only matches the first one that matches the condition

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

Copy the code

quantifiers

Now if you want to match a string with 10 consecutive occurrences of digits, as we learned above, you can use

const reg = /\d\d\d\d\d\d\d\d\d\d/
Copy the code

What if I want to match 10,000 occurrences? Wouldn’t that mean we’d have to use regular expression quantifiers instead?

Thanks to digger @scq000 for providing the memory map article portal: juejin.cn/post/684490…

So according to these definitions, let’s practice 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') //wCopy the code

The border

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

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

This is where our boundary characters come in, common boundary characters are

For example, if we want to match is, then both sides of is are word boundaries, so

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

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
Copy the code

So you can understand that \b and \b are used to determine whether the character to be matched is at the very edge of our word.

If we have a string like thisisthebest, we only want to match the th in this, you can use ^ to qualify the matching character to be the beginning of the entire string

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

The $is similar, restricting the matching character to the end of the entire string

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

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

Finally, take a 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)Copy the code

The preceding regular expression is translated as follows: Number 1 non-word boundary non-number 1 letter 2 non-letter 2 white space 1 Non-white space 1 word boundary

The result is a successful match

subexpression

So we have almost learned the basic regularity, do you need some interview questions to start the appetizer? Write a regular expression that matches the following three date formats:

The 2016-06-12 2016/06/12 2016.06.12Copy the code

At this point, someone might write a regular that looks like this

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

I regret 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
Copy the code

It is obvious that there should be a unified delimiter. To have a uniform delimiter requires a mechanism to capture the first delimiter and then keep the second delimiter consistent with it. This is where the backreference comes in.

grouping

The function of grouping can be achieved by using (), so that quantifiers can be applied to groups. The expressions included in () can be considered as a group, for example:

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

If grouping is used only for matching, it is only 10 percent of its function, and much more for backreferencing.

backreferences

To get back to our problem, match a date string like 2016-06-12, 2016/06/12, and a hidden condition is that the delimiter between my month and day needs to be the same as the first delimiter, otherwise the string like 2016-02/09 will also be matched. This is where we need to use a backreference, which means we need to reference the previously matched substring at the end of our re. 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 by the first grouping), \2 represents the second subexpression of the reference (matched by the second grouping), and so on. While \0 represents the entire expression.

Therefore, we can write the regular expression matching 2016-06-12, 2016/06/12 and 2016.06.12 as follows:

| or said, means to match one of them

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

Remember, a backreference requires grouping with () first

Grouping and backreferencing are also commonly used in string substitutions, with 1,1,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 can write 👇

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

Let’s do a similar one

Write a function to convert a hump string to a – concatenated string, such as getElementById –> get-element-by-id

Think 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
Copy the code

Write a function to convert the -concatenated string to a hump string, such as get-element-by-id –> getElementById

Think 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')
Copy the code

Start with a regular expression that determines a phone number

Think for a minute before you see the answer!!

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

foresight

There is a scenario where I want to match the adverb happily in the string happyHappily, and I can use proactive to meet my needs

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

The regular expression is parsed from the head of the text to the tail, which is called the “front”

When a regular expression matches a rule, the end of the text is checked for assertions. The assertion part is not included in the matched characters.

Can’t read it? Ok, let’s look at this question. It’s also a common interview question:

How do I separate a number with thousandths?

There is a toLocaleString method that has nothing to do with regex, so you can learn about it. Let’s see how to use regex to kill seconds.

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

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

That’s obviously not what we want, we just want the right hand side to be a multiple of 3, so we’re going to add $, and $is going to be predictive that the last character of this assertion must be the end of the string, so 11231234 matches from the head, and when we say 1, even though there are 3×2 numbers, But it is not the end of the string, so continue with the second 1 matching, which is followed by 3×2 digits and is the end of the string, so use /(\d)(? =(\d{3})+$)/, this will replace 11231234 with 11,231234. This result is closer to what we want than the previous step, but the right-hand side is not finished yet. So let’s go ahead and match 231234 on the right using the same rules. With the g modifier, we have /(\d)(? =(\d{3})+$)/g.

Does that make sense?

The interview questions,

Verify ID card Number

The regular ID card number may be 15 or 18 digits, with 15 digits being all digits, the first 17 digits being digits, and the last digit being a digit or X

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

Add a prototype method called trim to javascript’s string native object that intercepts whitespace before and after a string

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

The url of the params

Gets the parameters in the URL

If the parameter name is specified, return the value of the parameter or an empty string. If the parameter name is specified, return the entire parameter object or {}, return an array if more than one parameter of the same name exists

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 ''; }}Copy the code

Replace the blank space

From Leetcode: leetcode-cn.com/problems/ti…

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

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

Just go to LeetCode and write your code verification.

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

Verify that it is an email address

Rule definition:

• Use uppercase letters [A-z], lowercase letters [A-z], digits [0-9], underscores (_), minus -, and periods (.). Start, and need to repeat one to multiple +.

• The @ symbol must be included.

• @ must be followed by uppercase letters [A-z], lowercase letters [A-z], digits [0-9], underscores (_), minus signs (-), and periods (.), and must be repeated one to multiple times.

• Must end with a dot. Concatenate the upper and lower case letters [a-za-z]{2,4} for bits 廏 to 噕.

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;Copy the code

Fill in the function code to make it fully functional

Var STR = "Hello, <%=name%> <%=location%>"; function template(str) { // your code } var compiled = template(str); Compiled is: "Hello, Zhang Sam. Already ({name: "zhang 三", location:" XXX "});Copy the code

Think about it for a minute before you look at your answer

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

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

Example:

Var context = {name:"bottle",age:"15"} {name:"bottle",age:"15"} Cascaded variables can also be expanded to allow whitespace characters between delimiters and variablesCopy the code

When a regular expression contains a qualifier that accepts repetition, the common behavior is to match as many characters as possible (without matching the entire expression).

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 matches the entire string aabab. This is called greedy matching

{{name}} {age}} {age}} {age}} {age}} {age}} {age}} {age}

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

That is, use.*? To match

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

Of course, we can write it without 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"})Copy the code

Refer to the article

Juejin. Cn/post / 684490…

Juejin. Cn/post / 684490…

Juejin. Cn/post / 684490…

Write in the last

Share my possession of TS tutorials, from zero to high order all series, click a link, 0 RMB for www.yidengxuetang.com/pub-page/in…