Regular expression

.

Regular expression: the RegExp

Rules for handling strings

  • You can only handle strings
  • It is a rule: you can either verify that a string conforms to a rule (test) or capture the content of a string that conforms to the rule (exec/match…).
let str = "Good good study, day day up!";
//=> Learning regularity is to make rules (including numbers)
let reg = /\d+/;
reg.test(str); //=>false

str = "2019-08-12";
reg.exec(str); //=>["2019",index:0,inputs:" primitive string "]
Copy the code

Writing regular expressions

There are two ways to create it

//=> literal creation method (two slashes are wrapped between each other, which are used to describe the rule's metacharacters)
let reg1 = /\d+/;

//=> Constructor mode creates two arguments: metacharacter string, modifier string
let reg2 = new RegExp("\\d+");
Copy the code

A regular expression consists of two parts

  • metacharacters
  • The modifier
/* Common metacharacter */
//=>1. Set the number of occurrences of quantifier metacharacters* Zero to multiple + one to multiple? Zero or one {n} occurs n times {n,} occurs n to many {n,m} occurs n to m times//=>2. Special metacharacters: a single metacharacter or a combination of metacharacters indicates a special meaning\ escape character (normal -> special -> normal). Any character other than \n (newline) ^ which metacharacter to start with $which metacharacter to end with \n newline \d0~9Between a number \D not0~9A digit between (uppercase and lowercase mean opposite) \w Any character in digits, letters, and underscores \s a whitespace character (including Spaces, tabs, page breaks, etc.) \t a TAB character (a TAB key: Four Spaces) \ b matches a word boundary x | y x or y [xyz] a character in a character in x or y, or z [^ xy] any character other than x/y [a-z] of arbitrary characters [a-z this range specified09 -A-za-z_]===\w [^a-z] ===\w [^a-z] ===\w [^a-z] :) only matches but does not capture (? =) forward check (? !). Negative lessons//=>3. Common metacharacter: indicates its own meaning/zhufeng/ This re matches"zhufeng"
Copy the code
/* Regular expression modifiers: img*/I =>ignoreCase Ignores word case matching. M =>multiline Can match multiple lines. G =>global Global matching/* /A/.test('lalala') =>false /A/i.test('lalala') =>true */
Copy the code

Metacharacter detailed parsing

^ $

let reg = /^\d/;
console.log(reg.test("zhufeng")); //=>false
console.log(reg.test("2019zhufeng"));//=>true
console.log(reg.test("zhufeng2019"));//=>false
Copy the code
let reg = /\d$/;
console.log(reg.test("zhufeng")); //=>false
console.log(reg.test("2019zhufeng"));//=>false
console.log(reg.test("zhufeng2019"));//=>true
Copy the code
//=>^/$Do not add either: The string contains the content that complies with the rules
let reg1 = /\d+/;
//=>^/$Add both: the string must be consistent with the rule
let reg2 = /^\d+$/;

//=> Example: verify mobile phone number (11 digits, the first digit is 1)
let reg = /^1\d{10}$/;
Copy the code

\

//=>. Is not a decimal point, is any character except \n
let reg = 2.3 $/ / ^;
console.log(reg.test("2.3"));//=>true
console.log(reg.test("2 @ 3"));//=>true
console.log(reg.test("23"));//=>false

//=> Based on the escape character, so that it can only represent the decimal point
reg = $/ / ^ 2 \. 3;
console.log(reg.test("2.3"));//=>true
console.log(reg.test("2 @ 3"));//=>false

let str = "\\d";
reg = /^\d$/; //=>\d represents the numbers from 0 to 9
console.log(reg.test(str)); //=>false
reg = /^\\d$/; //=> Convert special coincidence to normal
console.log(reg.test(str)); //=>true
Copy the code

x|y

let reg = 18 | $29 / / ^;
console.log(reg.test("18")); //=>true
console.log(reg.test("29")); //=>true
console.log(reg.test("129")); //=>true
console.log(reg.test("189")); //=>true
console.log(reg.test("1829")); //=>true
console.log(reg.test("829")); //=>true
console.log(reg.test("182")); //=>true
/ / -- - direct x | y will mess priority problems, normally we write is accompanied by grouping parentheses, because parentheses change processing priority = > parentheses: grouping
reg = $/ / ^ 18 | (29);
console.log(reg.test("18")); //=>true
console.log(reg.test("29")); //=>true
console.log(reg.test("129")); //=>false
console.log(reg.test("189")); //=>false
//=> Can only be 18 or 29
Copy the code

[]

//1. The characters in brackets generally represent their own meanings
let reg = / ^ @ + $/;
console.log(reg.test("@")); //=>true
console.log(reg.test("+")); //=>true
console.log(reg.test("@ @")); //=>false
console.log(reg.test("@ +")); //=>false

reg = /^[\d]$/; //=>\d in brackets is still 0-9
console.log(reg.test("d"));//=>false
console.log(reg.test("\ \"));//=>false
console.log(reg.test("9"));//=>true

//2. There are no multiple digits in brackets
reg = $/ / ^ [18];
console.log(reg.test("1")); //=>true
console.log(reg.test("8")); //=>true
console.log(reg.test("18")); //=>false

reg = $/ / ^ [10-29]; //=>1 or 0-2 or 9
console.log(reg.test("1"));//=>true
console.log(reg.test("9"));//=>true
console.log(reg.test("0"));//=>true
console.log(reg.test("2"));//=>true
console.log(reg.test("10"));//=>false
Copy the code

Common regular expressions

  1. Verifies whether it is a significant number

    /* * Rule analysis * 1. The +- sign may or may not occur. * 2. A 0-9 can, more than the first can't is 0 (\ d | (1-9] [\ d +)) * 3. May or may not have a decimal part, but must be followed by a decimal point + number (\.\d+)? * /
    let reg = / ^ (+ -)? (\d|([1-9]\d+))(\.\d+)? $/;
    Copy the code
  2. Verify password

    //=> Digits, letters, and underscores (_)
    / / = > 6 ~ 16
    let val = userPassInp.value,
        reg = 16th {6} $/ ^ \ w /;
    let flag=reg.test(val);
    / * function checkPass (val) {if (val. Length < 6 | | val. The length > 16) {alert (' length must be between 6 and 16! '); return; } let area=['a','b'....'_']; //=> Contains digits, letters, and underscores. For (let I =0; i
    Copy the code
  3. Verify real name

    /^[u4E00-\u9FA5]$/ * 2 Name length 2 ~ 10 * 3. There may be translation, the Chinese character (· [\ u4E00 - \ u9FA5] {2, 10})} {0, 2 * /
    let reg = / ^ [\ u4E00 - \ u9FA5] {2, 10} (· [\ u4E00 - \ u9FA5] {2, 10})} {0, 2 $/;
    Copy the code
  4. Authenticating mailbox

    let reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
    
    //=> \w+((-\w+)|(\.\w+))*
    //1. Start with alphanumeric underscore (1 to multiple digits)
    //2. Can also be - alphanumeric underscore or. Alphanumeric underscore, overall zero to multiple times
    //=> The mailbox name can contain digits, letters, underscores (_), hyphens (-), and. Several components, but -/. Does not occur consecutively or as a starting point
    
    //=> @[A-Za-z0-9]+
    //1.@ followed by: number, letter (1-bit)
    
    //=> ((\.|-)[A-Za-z0-9]+)*
    //1. Add the name after @
    // multiple domains
    // Enterprise email [email protected]
    
    //=> \.[A-Za-z0-9]+
    / / 1. The match is the final domain name (com/.cn/.org/.edu/.net.)
    Copy the code
  5. Id Card Number

    * * * * * * * * * * * * * * * * * * * * * * * * * * * The last digit => X or number * the penultimate digit => even female odd male * The rest is calculated by the algorithm */
    //let reg = /^\d{17}(\d|X)$/;
    //=> The second function of the bracketing group: group capture, not only can capture the information of the large re match, but also can capture the content of each small group separately
    let reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/;
    reg.exec("130828199012040617"); / / = > [" 130828199012040617 ", "130828", "1990", "12", "04", "1", "7"...]. The result of the capture is an array containing the contents of each small group individually retrieved
    Copy the code

The difference between the two methods of re creation

The //=> constructor needs two slashes to represent a string
let reg = /\d+/g;
reg = new RegExp("\\d+"."g");

//=> Part of the regular expression is the value stored in the variable
//1. Both slashes are metacharacters (if the re contains the value of a variable, it cannot be created literally)
let type = "zhufeng";
reg = /^@"+type+"@$/; 
console.log(reg.test("@zhufeng@")); //=>false
console.log(reg.test('@"""typeeeee"@')); //=>true
//2. You can only use the constructor method in this case (because it passes the rule string, so it is the only way to concatenate string)
reg = new RegExp("^ @"+type+"@ $");
console.log(reg.test("@zhufeng@"));//=>true
Copy the code

Capture of re

A way to achieve regex capture

  • Method on RegExp. Prototype

    • exec
    • test
  • The String string. prototype supports regular expression handling methods

    • replace
    • match
    • splite
    • .
let str = "zhufeng2019yangfan2020qihang2021";
let reg = /\d+/;
The result of the capture is null or an array * first item: the content captured this time * Remaining items: the content captured separately in the corresponding small group * index: the initial index of the current captured content in the string * input: the original string * 2. For each exec execution, only one match can be caught, but by default, we execute a hundred times, and the result is always the first match, the rest of the catch is not * => "lazy" : the default catch is only the first */
console.log(reg.exec(str)); //=>["2019", index: 7, input: "zhufeng2019yangfan2020qihang2021"]
console.log(reg.exec(str)); / / = > [...] of "2019"

Let reg = /^\d+$/; let reg = /^\d+$/; console.log(reg.test(str)); //=>false console.log(reg.exec(str)); //=>null */
Copy the code

Lazy solutions

let str = "zhufeng2019yangfan2020qihang2021";
/* * reg.lastIndex: the starting index position of the current re for the next match * reason for lazy capture: by default, the value of lastIndex is not changed, each time it is looked up from the beginning of the string, so it always finds the first * solution: the global modifier g */
// let reg = /\d+/;
// console.log(reg.lastIndex); //=>0 the following matches are caught starting at STR index zero
// console.log(reg.exec(str));
// console.log(reg.lastIndex); //=>0 when the first match is caught, lastIndex remains unchanged, so exec will always find the first match from the beginning of the string

// let reg = /\d+/g;
// console.log(reg.exec(str)); / / = > [...] of "2019"
// console.log(reg.lastIndex); //=>11 After setting the global matching modifier g, lastIndex will change itself after the first match
// console.log(reg.exec(str)); / / = > [...] of "2020"
// console.log(reg.lastIndex); / / = > 22
// console.log(reg.exec(str)); / / = > [...] of "2021"
// console.log(reg.lastIndex); / / = > 32
// console.log(reg.exec(str)); //=>null The result of the next capture is null, but the lastIndex returns to the original value of zero, and the next capture starts from the first one...
// console.log(reg.lastIndex); / / = > 0
// console.log(reg.exec(str)); / / = > [...] of "2019"

// let reg = /\d+/g;
// if (reg.test(str)) {
// //=> Verify: only re and string matches we are capturing
// console.log(reg.lastIndex); //=>11 After the TEST match validation, LASTINDEX has been modified to the result of the first match, so the next capture will not start from scratch
// console.log(reg.exec(str)); / / = > [...] of "2020"
// }

//=> Required: Write a method execAll that can be executed once to capture the results of all matches (the preconditioned re must be set to the global qualifier g)
~ function () {
    function execAll(str = "") {
        //=> STR: string to be matched
        //=>this: instance of RegExp (regex for current operation)
        //=> The first thing to do is to verify that the current re is set to G. If G is not set, the loop cannot be captured again. Otherwise, it will cause an infinite loop
        if (!this.global) return this.exec(str);
        // ARY stores all the last captured information RES stores the contents of each capture (array)
        let ary = [],
            res = this.exec(str);
        while (res) {
            //=> Store each captured content RES[0] in an array
            ary.push(res[0]);
            //=> As long as the captured content is not NULL, the capture continues
            res = this.exec(str);
        }
        return ary.length === 0 ? null : ary;
    }
    RegExp.prototype.execAll = execAll; } ();let reg = /\d+/g;
console.log(reg.execAll("Mount Everest 2019@2020 Training"));
//=> The MATCH method in the string can be executed once, and all matches can be captured (if the re is also set to G).
console.log("Mount Everest 2019@2020 Training".match(reg));
Copy the code

Group capture of re

//=> ID card number
let str = "130828199012040112";
let reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(? :\d|X)$/;
console.log(reg.exec(str));
console.log(str.match(reg));
//=>["130828199012040112", "130828", "1990", "12", "04", "1", index: 0, input: "130828199012040112"]
//=> The first item: the result of the grand re match
//=> Remaining items: Each small group individually matches the captured results
//=> If you set grouping (change priority), but do not need to capture separately, can be based on? : to deal with
Copy the code
{0} => {0} => {0} => {0} => {0} =
let str = "{0} Year {1} Month {2} day";

Let reg = /\{(\d+)\}/; let reg = /\{(\d+)\}/; console.log(reg.exec(str)); console.log(str.match(reg)); / / / "{0}", "0",... * /

let reg = /\{(\d+)\}/g;
//console.log(str.match(reg)); / / = > [" {0} ", "{1}", "{2}"] many times match, the match can only match the big regular access to the content, information without access to a small group match
let aryBig=[],
    arySmall=[],
    res=reg.exec(str);
while(res){
    let [big,small]=res;
    aryBig.push(big);
    arySmall.push(small);
    res=reg.exec(str);
}
console.log(aryBig,arySmall); //=>["{0}", "{1}", "{2}"] ["0", "1", "2"]
Copy the code
//=> Third function of grouping: "grouping reference"
let str = "book"; //=>"good", "look", "moon", "foot"...
let reg = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/; //=> Group reference is to use "\ number" to make its representation and corresponding group appear exactly the same content
console.log(reg.test("book")); //=>true
console.log(reg.test("deep")); //=>true
console.log(reg.test("some")); //=>false
Copy the code

Cupidity of regular capture

let str = "Mount Everest 2019@2020 Training";
Greedy for re capture: By default, the longest result matched by the current re is captured
let reg = /\d+/g;
console.log(str.match(reg)); / / = > [" 2019 ", "2020"]

//=> Set after the quantifier metacharacter? : Uncupidity of capture (obtained as the shortest result of regular matching)
reg = /\d+? /g;
console.log(str.match(reg)); //=>["2", "0", "1", "9", "2", "0", "2", "0"]
Copy the code

The five functions of question marks in re:

  • The left side of the question mark is a non-quantifier metacharacter: itself represents a quantifier metacharacter, appearing zero to once
  • To the left of the question mark is the quantifier metacharacter: ungrabbility
  • (? 🙂 matches only but does not capture
  • (? =) Forward check
  • (? !). Negative lessons

Other methods of re capture

  1. Test can also capture (meaning match)

    let str = "{0} Year {1} Month {2} day";
    let reg = /\{(\d+)\}/g;
    console.log(reg.test(str)); //=>true
    console.log(RegExp. $1); / / = > "0"
    
    console.log(reg.test(str)); //=>true
    console.log(RegExp. $1); / / = > "1"
    
    console.log(reg.test(str)); //=>true
    console.log(RegExp. $1); / / = > "2"
    
    console.log(reg.test(str)); //=>false
    console.log(RegExp. $1); //=>"2" stores the result of the last capture
    
    //=>RegExp.$1~RegExp.$9: retrieves information about the first to ninth groups after the current re match
    Copy the code
  2. The method used to implement a replacement in the replace string (usually with a re)

    let str = "zhufeng@2019|zhufeng@2020";
    //=> Replace "zhufeng" with "Everest"
    //1. Only one regex can be replaced at a time
    / * STR = STR. Replace (" zhufeng ", "mount Everest"). The replace (" zhufeng ", "mount Everest"); console.log(str); * /
    //2. Using regex is easier
    str = str.replace(/zhufeng/g."Everest");
    console.log(str);
    Copy the code
    let str = "zhufeng@2019|zhufeng@2020";
    // replace "zhufeng" with "zhufengpeixun"
    //str=str.replace("zhufeng","zhufengpeixun").replace("zhufeng","zhufengpeixun");
    / / "zhufengpeixunpeixun @ 2019 | zhufeng @ 2020" every replacement from string to find it the first position (similar to the regular captured lazy)
    
    //=> This can be implemented based on regular G
    str = str.replace(/zhufeng/g."zhufengpeixun");
    Copy the code

    Example: Processing the time string

    let time = "2019-08-13";
    //=> changes to "August 13, 2019"
    let reg = / ^ (\ d {4}) - (\ d {1, 2}) - $/ (\ d {1, 2});
    
    //=> This can be implemented
    Replace (reg,"$1 year $2 month $3 day "); //time = time.replace(reg,"$1 year $2 month $3 day ");
    //console.log(time); //=> August 13, 2019
    
    Replace ([reg],[function])
    //1. REG and TIME are matched, and the passed function is executed several times (and once it is matched).
    //2. Not only does REPLACE execute the method, but REPLACE also passes the argument information to the method (the same information as exec captures: the content of the large re match, the information of the small group match....)
    //3. Replace the current grand re match with whatever we return in the function
    / * time = time. Replace (reg, (big, $1, $2, $3) = > {/ / = > here at $1 to $3 is our own set of variable console log (big, $1, $2, $3); }); * /time = time.replace(reg,(... arg)=>{let[, $1, $2, $3]=arg;
        $2.length<2? $2="0"+ $2:null;
        $3.length<2? $3="0"+ $3:null;
        return $1+"Year"+ $2+"Month"+ $3+"Day";
    });
    Copy the code

    Capitalize the first letter

    let str = "Good good study, day day up!";
    let reg = /\b([a-zA-Z])[a-zA-Z]*\b/g;
    //=> The function is executed six times, each time passing the regular match information to the function
    / / = > every ARG: [" good ", "g"] [" good ", "g"] [" study ", "s"]...str = str.replace(reg,(... arg)=>{let [content,$1]=arg;
        $1= $1.toUpperCase();
        content=content.substring(1);
        return $1+content;
    });
    console.log(str); //=>"Good Good Study, Day Day Up!"
    Copy the code

    What is the maximum number of occurrences of a character in a string?

    /*== */
    let str = "zhufengpeixunzhoulaoshi";
    let obj = {};
    [].forEach.call(str, char => {
    	if (typeofobj[char] ! = ="undefined") {
    		obj[char]++;
    		return;
    	}
    	obj[char] = 1;
    });
    let max = 1,
    	res = [];
    for (let key in obj) {
    	let item = obj[key];
    	item > max ? max = item : null;
    }
    for (let key in obj) {
    	let item = obj[key];
    	if(item === max) { res.push(key); }}console.log('most frequently occurring character:${res}Appeared,${max}Time `);
    
    /*== wangxin: sort ==*/
    let str = "zhufengpeixunzhoulaoshi";
    str = str.split(' ').sort((a, b) = > a.localeCompare(b)).join(' ');
    // console.log(str); //=>"aeefghhhiilnnoopsuuuxzz"
    let ary = str.match(/([a-zA-Z])\1+/g).sort((a, b) = > b.length - a.length);
    // console.log(ary); //=>["hhh", "uuu", "ee", "ii", "nn", "oo", "zz"]
    let max = ary[0].length,
    	res = [ary[0].substr(0.1)];
    for (let i = 1; i < ary.length; i++) {
    	let item = ary[i];
    	if (item.length < max) {
    		break;
    	}
    	res.push(item.substr(0.1));
    }
    console.log('most frequently occurring character:${res}Appeared,${max}Time `);
    
    /*== Yellow Sea boat: try to find ==*/ from largest to smallest
    let str = "zhufengpeixunzhoulaoshi",
    	max = 0,
    	res = [],
    	flag = false;
    str = str.split(' ').sort((a, b) = > a.localeCompare(b)).join(' ');
    for (let i = str.length; i > 0; i--) {
    	let reg = new RegExp("([a-zA-Z])\\1{" + (i - 1) + "}"."g");
    	str.replace(reg, (content, $1) => {
    		res.push($1);
    		max = i;
    		flag = true;
    	});
    	if (flag) break;
    }
    console.log('most frequently occurring character:${res}Appeared,${max}Time `);
    Copy the code

    Other methods: formatTime, queryURLParams, Cart

    ~ function () {
    	/ * * formatTime: Template rules :{0}-> year {1~5}-> month/day/minute/second * @return * [string] Formatted time string * by  zhufengpeixun on 2019/08/13 */
    	function formatTime(templete = "{0} year {1} month {2} day {3} {4} minutes {5} seconds") {
    		let timeAry = this.match(/\d+/g);
    		return templete.replace(/\{(\d+)\}/g, (... [, $1]) = > {let time = timeAry[$1] | |"00";
    			return time.length < 2 ? "0" + time : time;
    		});
    	}
    
    	/ * * queryURLParams: * @params * @return * [object] Stores all question mark parameter information as key-value pairs and returns * by zhufengpeixun on 2019/08/13 */
    	function queryURLParams() {
    		let obj = {};
    		this.replace(/([^?=&#]+)=([^?=&#]+)/g, (... [, $1, $2]) => obj[$1] = $2);
    		this.replace(/#([^?=&#]+)/g, (... [, $1]) => obj['HASH'] = $1);
    		return obj;
    	}
    
    	/* * Cart: Perform million-year processing on large numbers * @params * @return * [string] String after million-year * by zhufengpeixun on 2019/08/13 */
    	function millimeter() {
    		return this.replace(/ \ d {1, 3} (? =(\d{3})+$)/g, content => content + ', ');
    	}
    	
    	/* Extends to the built-in string.prototype class */
    	["formatTime"."queryURLParams"."millimeter"].forEach(item= > {
    		String.prototype[item] = eval(item); }); } ();Copy the code