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 specified0-9a-za-z_]===\w [^a-z] ===\w [^a-z] :) only matches but does not capture (? =) forward check (? !). Negative lessons//=>3. Common metacharacter: indicates its own meaning/xiaoming/ This regex matches"xiaoming"
Copy the code
/* Regular expression modifiers: img*/I =>ignoreCase ignores word case matching m =>multiline can match multiple lines g =>globalThe global matching/* /A/.test('lalala') =>false /A/i.test('lalala') =>true */
Copy the code
Metacharacter detailed parsing
^ $
let reg = /^\d/;
console.log(reg.test('xiaoming')); //=>false
console.log(reg.test('2019xiaoming')); //=>true
console.log(reg.test('xiaoming2019')); //=>false
Copy the code
let reg = /\d$/;
console.log(reg.test('xiaoming')); //=>false
console.log(reg.test('2019xiaoming')); //=>false
console.log(reg.test('xiaoming2019')); //=>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}$/;
// /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
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('and')); //=>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('and')); //=>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(The '@')); //=>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
-
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
-
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
-
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
-
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
-
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
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 = 'xiaoming2019yangfan2020qihang2021';
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: "xiaoming2019yangfan2020qihang2021"]
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 = 'xiaoming2019yangfan2020qihang2021';
/* * 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('Xiao Ming 2019@2020 Take off'));
//=> 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('Xiao Ming 2019@2020 Take off'.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 = 'Xiao Ming 2019@2020 Take off';
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
-
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
-
The method used to implement a replacement in the replace string (usually with a re)
let str = 'xiaoming@2019|xiaoming@2020'; // change "xiaoming" to "xiaoming" //1. Only one regex can be replaced at a time / * STR = STR. Replace (" xiaoming ", "Ming"). The replace (" xiaoming ", "Ming"); console.log(str); * / //2. Using regex is easier str = str.replace(/xiaoming/g.'Ming'); console.log(str); Copy the code
let str = 'xiaoming@2019|xiaoming@2020'; // replace "xiaoming" with "xiaomingpeixun" //str=str.replace("xiaoming","xiaomingpeixun").replace("xiaoming","xiaomingpeixun"); / / "xiaomingpeixunpeixun @ 2019 | xiaoming @ 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(/xiaoming/g.'xiaomingpeixun'); 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 + 'years' + $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?
/*== the first type ==*/ let str = 'xiaomingshigeguaihaizi'; 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 `); /*== the second type ==*/ let str = 'xiaomingshigeguaihaizi'; 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 `); /*== the third type ==*/ let str = 'xiaomingshigeguaihaizi', 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 xiaomingpeixun 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] Store all question marks as key-value pairs and return * by Xiaomingpeixun 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; } /* * Chromatic: Implements million-year processing of large numbers * @params * @return * [string] Million-year string * by Xiaomingpeixun 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