preface

  • Reading this article will take about 30 minutes \color{red}{30 minutes}
  • In this
    detailed \color{red}{red}
    A:

    1. What is a regular expression
    2. Regular expression processing [match] [capture]
    3. Create a regular
    4. metacharacters
    5. The modifier
    6. The function of the parentheses
    7. The function of the brackets
    8. The role of question marks
    9. Regular matching [test]
    10. A variety of ideas for re capture
    11. Practice: Capitalize the first letter of a word
    12. Exercise: Date string formatting
    13. Handles and encapsulates a universal method of formatting a time string
    14. Obtain the HASH information of the question mark in the URL address
  • If you have any questions, please leave a message to me. I will reply when I see it. If I can’t solve it, we can also discuss and learn together. If you think there is any mistake, please kindly comment and correct me. Thank you very much. I hope to learn and make progress together with you in the future.
  • The next article will be updated as soon as possible, and the already written article will be modified intermittently in the future as understanding deepens or illustrations are added.
  • If you find this article helpful, please give it a thumbs-up. Thank you!

Regular expression

  • A regular expression is a rule for manipulating strings
  • Regular expressions are rules composed of metacharacters and modifiers

Regular expression processing

  • You can only handle strings
    • [Match] Verifies that the string complies with this rule
    • Capture The information in a string that conforms to a rule

Create a regular

Literal modelet reg1 = /\d+/img;

  • Literal style, two slashes wrapped around it, are its metacharacters
  • The last slash is followed by the modifier,

Constructor modelet reg2 = new Regexp('\\d+');

  • Constructor, passing two strings,
  • The first string contains metacharacters
    • The reason there are two slashes is because you’re passing two strings, and one right slash in a string doesn’t make any sense, so you need to write two each time you use it, and one right slash is for escaping.
  • The second string is the modifier

metacharacters

Quantifier metacharacter [how many occurrences of a metacharacter to the left]

  • *Zero to many times
  • +One or several times
  • ?Zero or once
  • {n}A n time
  • {n,}N to multiple occurrences
  • {n,m}N to m occurrences

3. A metacharacter of special significance.

  • \Escape characters (normal -> Special -> Normal)
  • .Any character except \n (newline character)
  • ^Which metacharacter to start with
  • $Which metacharacter to end with
  • \nA newline
  • \dA number between 0 and 9
  • \DCharacters that are not numbers between 0 and 9 (uppercase and lowercase mean opposite)
  • \wAny character contained in digits, letters, and underscores
  • \sA whitespace character (including Spaces, tabs, page feeds, etc.)
  • \tOne TAB (one TAB key: four Spaces)
  • \bMatches the boundaries of a word
  • x|yA character in x or y[Generally used with parentheses grouping, can change the default priority]
  • [xyz]A character in x or y or Z
    • Brackets have the function of demagnetization. Metacharacters in brackets are their own meanings
    • But like\dA metacharacter is a metacharacter, which itself means a number between 0 and 9
    • The multidigit number in brackets stands for something or other, not a multidigit number
  • [^xy]Any character except x/y
  • [a-z]Specifies any character in the range a-zSuch as [0-9a-zA-Z_]===\w [0-9] === \d
  • [^a-z]Take the opposite of the last one.
  • (a)A grouping symbol in a re
    • Change priorities
    • Packet capture
  • (? :)Match only, no capture
  • (? =)Positive study
  • (? !).Negative lessons

Ordinary metacharacter

  • \xxx\

The modifier

  • i =>ignoreCase Ignore word case matching
  • m =>multiline Multiple line matching is possible
  • g =>global The global matching

The function of the parentheses

  1. [Priority] : You can change the default priority
  2. [Group capture] : The first capture, in addition to the big re matching information captured, and can also individually capture each small group matching information captured

The function of the brackets

  1. [Group reference]:\ 1or\ 2. On behalf ofAfter carvingOut andThe first one/The second. Group exactly the same content
    let reg = /^[a-zA-Z\d][a-zA-Z\d]\2\1$/; // ABBA
Copy the code

The various functions of question mark in regularization

  • When? The left side is a nonquantifier metacharacter: is itself a quantifier metacharacter, allowing the content on the left to appear 0~1 times/\w? /
  • When? On the left is the quantifier metacharacterHis aim was to overcome greed in capture/\d? /g
  • (? : : The current group is matched but not captured
  • (? =) : Forward lookup (assertion) can be performed only if conditions are met
  • (? !). : Negative pre-check (assertion), only if the condition is not met
    let reg = / ^ [a zA - Z \ d] 6 16th} {$/; The password can contain 6-16 lowercase letters, uppercase letters, and digits.
    // Complex password processing: must contain both uppercase and lowercase letters and numbers
    // Negative pre-check version
    let reg = / ^ (? ! \d+$)(? ! [a-z]+$)(? ! [A-Z]+$)(? ! [a-z\d]+$)(? ! [A-Z\d]+$)(? ! [a zA - Z] + $) [a zA - Z \ d] 6 16th} {$/;
    // Forward version check
    let reg = / ^ (? =[a-zA-Z]*\d+[a-zA-Z]*)(? =[A-Z\d]*[a-z]*[A-Z\d]*)(? / = []) 
Copy the code

Re match: re object.test (string)

    // Re match: re object.test (string)
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    // ^ and $: start with and end with this thing
    let reg = /\d+/; // As long as the string contains one or more numbers
    console.log(reg.test('hahahahaha')) // false
    console.log(reg.test('hahahahaha2021')) // true

    reg = /^\d+/; // The string must start with one or more digits
    console.log(reg.test('hahahahaha')) // false
    console.log(reg.test('hahahahaha2021')) // false
    console.log(reg.test('2021hahahahaha')) // true

    reg = /\d+$/; // The string must end with one or more digits
    console.log(reg.test('hahahahaha')) // false
    console.log(reg.test('hahahahaha2021')) // true
    console.log(reg.test('2021hahahahaha')) // false
    
    reg = /^\d+$/; // A string can be one or more digits
    console.log(reg.test('hahahahaha')) // false
    console.log(reg.test('hahahahaha2021')) // false
    console.log(reg.test('2021hahahahaha')) // false
    console.log(reg.test('2020hahahahaha2021')) // false
    console.log(reg.test('20202021')) // true

    reg = /^\d$/; // A string can only be a number
    console.log(reg.test('1')) // true

    reg = 2.6 $/ / ^;
    console.log(reg.test('2.6')); // true
    console.log(reg.test('2 + 6')); // true
    console.log(reg.test('286')); // true
    console.log(reg.test('26')); // false
    console.log(reg.test(6 ` ` 2)); // false the second line cannot be a newline because the second rule is.


    reg = $/ / ^ 2 \. 6; // Escape characters can turn special characters into ordinary characters, or ordinary characters into special characters
    console.log(reg.test('2.6')); // true // The value can only be 2.6
    console.log(reg.test('2 + 6')); // false
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    // \ Escape characters
    reg = /^\\d$/; // The string can only be a right slash and d
    console.log(reg.test('d')) / / false,
    console.log(reg.test('\d')) // false
    console.log(reg.test('\\d')) // true
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

    / / x | y must be accompanied by the use of parentheses
    let reg1 = | $6 / / ^ 2;
    console.log(reg1.test('2')); // true
    console.log(reg1.test('3')); // true
    console.log(reg1.test('23'));// true
    console.log(reg1.test('4')); // true
    let reg2 = $/ / ^ 2 | (6);
    console.log(reg2.test('2')); // true
    console.log(reg2.test('3')); // true
    console.log(reg2.test('23'));// false
    console.log(reg2.test('4')); // false
    let reg3 = / ^ | 56 $14 /;
    console.log(reg3.test('14')); // true
    console.log(reg3.test('56')); // true
    console.log(reg3.test('146'));// true
    console.log(reg3.test('145')); // true
    console.log(reg3.test('156')); // true
    console.log(reg3.test('1456')); // true
    console.log(reg3.test('16')); // false

    let reg4 = $/ / ^ 14 | (56);
    console.log(reg4.test('14')); // true
    console.log(reg4.test('56')); // true
    console.log(reg4.test('146'));// false
    console.log(reg4.test('145')); // false
    console.log(reg4.test('156')); // false
    console.log(reg4.test('1456')); // false
    console.log(reg4.test('16')); // false



    // [xyz] [^xy] [a-z] [^a-z]
    let reg5 = $/ / ^. [+]
    console.log(reg5.test('a')); //false
    console.log(reg5.test('aaaa')); //false
    console.log(reg5.test('. ')); //true
    console.log(reg5.test('+')); //true 

    // \d is itself a metacharacter, which itself means a number between 0 and 9
    let reg6 = /^[\d]$/;
    console.log(reg6.test('9')); //true
    console.log(reg6.test('d')); //false 

    let reg7 = $/ / ^ [12-369]; // The multiple digits in parentheses represent something or other, not multiple digits
    console.log(reg7.test('12')); // false
    console.log(reg7.test('369')); // false
    console.log(reg7.test('the'));// false
    console.log(reg7.test('25')); // false
    console.log(reg7.test('40')); // false
    console.log(reg7.test('1')); // true
    console.log(reg7.test('2')); // true
    console.log(reg7.test('3')); // true
    console.log(reg7.test('6')); // true
    console.log(reg7.test('9')); // true
    console.log(reg7.test('4')); // false

/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    // Requirements: Match an age 18-65
    // How to do this
    let ageReg = /^((1[8-9])|([2-5]\d)|(6[0-5]))$/

    // Requirement: verify mobile phone number
    // 11 digits, starting with 10 digits
    // However, true regex can never be verified, so it is easy to verify that the format is correct
    let phoneReg = /^1\d{10}$/

/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    // Requirement: verify password
    // It is a string of 6 to 16 characters, including letters and numbers
    let passReg = / ^ [0-9 a zA - Z] 6 16th} {$/;

    // Requirement: verify real name
    // If you want to write a letter, you can write a letter.
    /* Chinese code range */`[\u4E00-\u9FA5]`
    let chineseNameReg = / ^ [\ u4E00 - \ u9FA5] {2, 10} (· [\ u4E00 - \ u9FA5] {1, 10})? $/;
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    // Requirement: verify mailbox
    // If (@) {// if (@)
    // Alphanumeric underscores (_) are standard names. You can have a bar and a dot, but they do not start or continue.
    /* Chinese code range */`[\u4E00-\u9FA5]`
    let emailReg = / ^ [\ u4E00 - \ u9FA5] {2, 10} (· [\ u4E00 - \ u9FA5] {1, 10})? $/;
    // More complete validation
    let emailReg2 = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
    / / \ w + ((\ w +) | (. \ \ w +)) * Numbers, letters, underscores is the standard name, can appear in the bar and points, but not for a start, and can't appear in a row, for example: zhou -. Xiao this is wrong
    / / @
    // [A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+
    // [A-Za-z0-9]+\.[A-Za-z0-9]+ qq.com 163.cn
    / / ((\ | -) [A Za - z0-9] +) *. Com - XXX enterprise email [email protected] * /
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Copy the code

Re capture: re object. Exec (string)

  • Captures the content of the string that matches the regular matching rule
    • If nothing in the string matches the re, the result is null

Features of re capture

  1. [‘ lazy ‘], perform one or more capture, can only capture the first matching informationOther matching information cannot be captured
    • The prototype object for the re has a public property, lastIndex, which holds the index for the next search, unchanged by default, and is 0. So each capture is searched from the first character, so only the first match can ever be caught
    • Regular expressions have a modifier g that sets two values (global: false/true). The default value is false. This modifier is global.
    • [Important] But if you use a regular rule with the g modifier, either test or exec will modify lastIndex, so if you use it consecutively, you will have a problem !!!!!
        let str = 'lsw123lsw'
            reg = /\d+/,
            reg1= /\d+/g;
        if(reg.test(str)){
            console.log(reg.exec(str));/ / 123
        }
        if(reg1.test(str)){
            console.log(reg.exec(str));//null
        }
    Copy the code
  2. Regular capture is also greedy
    • Each capture of the re is based on the longest match
        let str = 'lsw2021',
            reg = /\d+/g,
            reg2 = /\d+? /g;
        console.log(str.match(reg));/ / -- - > [2021]
        console.log(str.match(reg2));/ / -- - > [' 2 ', '0', '2', '1']
    
    Copy the code

Resolve the feature of regex capture laziness

[Method 1] modifiergCan solve the re capturelazyThe characteristics of

    let str = 'lsw',
        str1 = 'lsw2020happy2021everyday'
        reg = /\d+/,
        reg1 = /\d+/g;
    console.log(reg.test(str));
    console.log(reg.exec(str)); // null
    // Generally, a match is made before capturing. If not, no capture is carried out
    reg.test(str)?console.log(reg.exec(str)):null;
    console.log(reg.exec(str1)); // ["2020", index: 3, input: "lsw2020happy2021", groups: undefined]
    // The first item is the information captured by the re,

    // The laziness of the re capture
    console.log(reg1.lastIndex);/ / 0
    console.log(reg1.exec(str1)); // ["2020", index: 3, input: "lsw2020happy2021", groups: undefined]
    console.log(reg1.lastIndex);/ / 7
    console.log(reg1.exec(str1)); // ["2021", index: 3, input: "lsw2020happy2021", groups: undefined]
    console.log(reg1.lastIndex);/ / 16
    console.log(reg1.exec(str1)); //null
    // The lastIndex is reset to 0 again
    console.log(reg1.lastIndex);/ / 0
    console.log(reg1.exec(str1)); //null


Copy the code
To catch all matches at once, write a method execAll on the regular prototype
    RegExp.prototype.execAll = function execAll(str){
        // this===>reg STR ===> String
        str+=' '; // Whatever format is passed in, convert it to a string first
        // Regex capture must be set to the global modifier
        // g is not set to catch only once, each time not null, will become an infinite loop
        if(!this.global){
            return this.exec(str);
        }
        // Loop through exec until the result is null, storing the information captured each time
        let arr = [],
            result;
            while(result = this.exec(str)){ // This condition does two things: @1 gets the result and pays result @2 to check if result is null. If so, the loop ends
                // Result stores the result of each capture.
                arr.push(result[0]);
            }
            return arr;
    };
Copy the code

[Method 2] String match method

  • String.prototype.matchUsed with a regular expression, it captures everything in the current string that conforms to the regular rules
  • [Match has its own limitations (if the group capture is set and the G modifier is used at the same time)] : If the re is set with the G modifier, the information captured based on match only contains the matches of the large re, and the information matched by the small groups alone cannot be obtained. If g is not set, the result of the exec execution is the same
    let str = 'lsw2020happy2021everyday'
        reg = /\d+/,
        reg1 = /\d+/g;
    console.log(str.match(reg1)); / / / "2020", "2021"]
    console.log(str.match(reg)); // ["2020", index: 3, input: "lsw2020happy2021", groups: undefined]
Copy the code

【 However, match has its own limitations 】 EG. The regular processing of ID card 【 Get the corresponding digit to get the corresponding data 】

    let id = '210404199504182117';
    let reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(? :X|\d)$/g;
    let reg1 = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(? :X|\d)$/;
    console.log(id.match(reg));/ / / "210404199504182117"
    console.log(id.match(reg1));// ["210404199504182117", "210404", "1995", "04", "18", "21", "1", index: 0, input: "210404199504182117", groups: undefined]
Copy the code

The re processes the time string


[Regular capture method 2] Using regular matching to achieve the capture

  • The RegExp class has a static private property $
    • $&Indicates the matching result of the test executionRegExp.$&
    • $1-9Stores the first to ninth small packet matching information captured this timeRegExp.$1~9
     let str = 'lsw123lsw'
            reg = /\d+/,
            reg1= /\d+/g,
            reg2 = /(\d)\d+(\d)/g;
    reg1.test(str);
    console.log( RegExp['$&']); / / = = = = > '123'

    reg2.test(str);
    console.log( RegExp['$&']); / / = = = = > '123'
    console.log( RegExp['$1']); / / = = = = > '1'
    console.log( RegExp['$2']); / / = = = = > '2'

Copy the code

[Regular capture method 3] using the string method Repalce to achieve the capture

  • repalce: Only one match can be replaced at a time
    let str = 'zhenbucuo2020zhenbucuo2021';
    str = str.replace('zhenbucuo'.'That's nice.'); // '2020zhenbucuo2021'
    str = str.replace('zhenbucuo'.'That's nice.'); // '真不错2020真不错2021'
    console.log(str);
Copy the code
  • But it’s not possible to do replace more than once for some requirements
    1. Replace is usually used in conjunction with the re: Find everything in the STR that matches the re and replace everything in turn with ‘what you want’, but with the g modifier.
        let str = 'zbc2020zbc2021';
        str = str.replace('zbc'.'zbcZzsl'); // 'zbcZzslZzsl2020zbcZzsl2021'
        str = str.replace(/zbc/g.'zbcZzsl'); // 'zbcZzsl2020zbcZzsl2021'
        console.log(str);
    Copy the code
    1. If the replace second argument is a callback function. The first argument is a re,
      • Match the re with the string, and the callback function is executed several times
      • Not only does the callback function get executed, but it also passes argument information to the callback function:
        • Pass the result of each regex match to the callback function
        • What is returned by the callback function equivalent to replacing the portion of the current re match with what
        let str = 'zbc2020zbc2021';
        // If the re matches twice, the callback function is executed twice
        str = str.replace(/\d+/g.function(val){
            console.log(val);// @1 2020 @2 2021
            // What does the callback return, equivalent to replacing the portion of the current re match with what
            return The '@'+val;
        }); 
        console.log(str); // zbc@2020zbc@2021
    Copy the code
        // Requirement: replace {number} in the string with the contents of the specified item in the array, e.g. {2} with the contents of arr[2]
        let str = 'My name is {0}, I am a {1} child, I am {2} years old, I like {3}', arr = ['lsw'.'male'.'18'.'Code'];
        // Add the number to the index
        // Get the {number} from the big re and the number from the small group
        str = str.replace(/\{(\d+)\}/g.function(val,$1){
            // val-----> Information for each grand re match {number}
            // $1-----> The number of messages that the first packet matches each time
            console.log(arguments); 
            / / [" {0} ", "0", 5, "my name is {0}, I am a {1} child, this year I {2}, {3} I like", the callee: ƒ, Symbol (Symbol. The iterator) : ƒ]
            console.log(val);@1 {0} @2 {1} @3 {2} @4 {3}
            // What does the callback return, equivalent to replacing the portion of the current re match with what
            return arr[$1];// @1 LSW @2 male @3 18 @4 type code
        }); 
        console.log(str); // 'My name is LSW, I am a boy, I am 18 years old, I like to type code'
    Copy the code

  • Exercise: Capitalize the first letter of a word
        let str = 'good good study! day day up! ',
            reg = /\b([a-zA-Z])([a-zA-Z]*)\b/g;
        str = str.replace(reg,function(_, $1, $2){
            // val -----> information about each large re match ------ words
            // $1 -----> each time the first small packet matches the information ------ first letter of the word
            // $2 -----> each time the first small packet matches the information ------ remaining letters of the word
    
            console.log(arguments); 
            ƒ // ["good", "g", "ood", 0, "good good study! Day day up!", callee: ƒ, Symbol(Symbol.
            //console.log(val); // @1 good @2 good @3 study @4 day @5 day @6 up
            console.log($1);// @1 g @2 g @3 s @4 d @5 d @6 u
            console.log($2);// @1 ood @2 ood @3 tudy @4 ay @5 ay @6 p
    
            // What does the callback return, equivalent to replacing the portion of the current re match with what
            return $1.toUpperCase()+$2;// @1 Good @2 Good @3 Study @4 Day @5 Day @6 Up
        }); 
    Copy the code

  • Exercise: Date string formatting
        // Template compilation to implement
        let str = 'the 2021-7-6 15:51:8',
            arr = str.match(/\d+/g); // Get all the time numbers
            reg = /\{(\d+)\}/g,
            template = '{0} year {1} Month {2} day {3} {4} minutes {5} seconds';// Write the template
    
        template = template.replace(reg,function($1, $2){
            // val-----> Information for each grand re match {number}
            // $1-----> The number of messages that the first packet matches each time
            console.log($1);@1 {0} @2 {1} @3 {2} @4 {3} @5 {4} @6 {5}
            console.log($2);// @1 0 @2 1 @3 2 @4 3 @5 4 @6 5
            let val = arr[$2] | |'00'; // Get data or 00
            if(val.length<2)val = '0'+val; // There is only one bit of padding
            // What does the callback return, equivalent to replacing the portion of the current re match with what
            return val;// @1 2021 @2 07 @3 06 @4 15 @5 51 @6 08
        }); 
    Copy the code

String handling related method encapsulation

Encapsulate a time string template
    @params template[string]: {0, 1, 2, 3, 4, 5: Year, month, day, hour, minute, second} * @return * [string]: The last desired time format string * */
    String.prototype.formatTime = function formatTime(template) {
        template = template || '{0} year {1} Month {2} day {3} {4} minutes {5} seconds';
        let arr = this.match(/\d+/g);
        return template.replace(/\{(\d+)\}/g.(_, $1) = > {
            let val = arr[$1] | |'00';
            if (val.length < 2) val = '0' + val;
            return val;
        });
    };
Copy the code
Obtain the HASH and question mark information in the URL address
    * @params * @return * [object]: an object containing question mark parameters and hash values * */
    String.prototype.queryURLParams = function queryURLParams(){
        let obj = {};
        this.replace(/#([^?=#&]+)/g.(_, $1) = >obj['HASH'] = $1);
        this.replace(/([^?=#&]+)=([^?=#&]+)/g.(_, $1, $2) = >obj[$1] = $2);
        return obj;
    }
    
    let url1 = 'http://www.hahahahah.com/?name=LSW&age=18&sex=male#CEO';
    console.log(url1.queryURLParams());

Copy the code