Front-end star
1. The creation and use of regular expressions
1.1 Create regular expressions
-
Use regular expression literals to
const reg = /[a-z]\d+[a-z]/i;
/ /
include the content of regular expressions,[a-z]
letters,\d
numbers, and the+
preceding (\d
) repeated one or more times, toi
indicate modifiers, regular expressions ignore case- Advantages: simple and convenient and no need to consider secondary escaping
- Disadvantages: Sub-content cannot be reused, too long regularity leads to poor readability
-
Use RegExp constructor
const alphabet = '[a-z]'; const reg = new RegExp(`${alphabet}\\d+${alphabet}`, 'i');
- Advantages: Sub-content can be reused, and readability can be improved by controlling the granularity of sub-content
- Disadvantages: The problem of secondary escaping is very easy to cause bugs
const reg = new RegExp(`\d+`); reg.test('1'); // false reg.test('ddd'); // true
1.2 Use regular expressions
-
RegExp.prototype.test()
const reg = /[a-z]\d+[a-z]/i; reg.test('a1a'); // true reg.test('1a1'); // false reg.test(Symbol('a1a')); // TypeError
Input: The input string is required. If the input is not a string type, the type conversion will be attempted. If the conversion fails, a TypeError will be
output: true or false, indicating that the match is successful or failed -
RegExp.prototype.source (content) and RegExp.prototype.flags (modifiers and sort them in ascending order)
const reg = /[a-z]\d+[a-z]/ig; reg.source; // "[a-z]\d+[a-z]" reg.flags; // "gi"
-
RegExp.prototype.exec() 和 String.prototype.match()
const reg = /[a-z]\d+[a-z]/i; reg.exec('a1a'); // ["a1a", index: 0, input: "a1a", groups: undefined] reg.exec('1a1'); // null 'a1a'.match(reg); // ["a1a", index: 0, input: "a1a", groups: undefined] '1a1'.match(reg); // null
Input: RegExp.prototype.exec requires input of a string, and will try to convert when it encounters a non-string type;
String.prototype.match requires input of a regular expression, if it encounters other types, it will first try to convert to a string, and then use the string as source creates regular expressionsOutput: match success, return match result, match failure, return null
Since the data format returned by String.prototype.match is not fixed, it is recommended to use RegExp.prototype.exec in most cases
- RegExp.prototype.lastIndex
Note: lastIndex will not reset by itself, only reset to 0 when the last match fails, so when you need to use the same regular expression repeatedly, please match new characters every time Reset lastIndex before the string! - String.prototype.replace()、String.prototype.search()、String.prototype.split()
2. Three application scenarios
2.1 Scenario 1: Regular and numerical
Numerical judgment process:
/[0-9]+/
: Incomplete match (as long as it contains numbers)/^\d+$/
: Cannot match signed values and decimals/^[+-]?\d+(\.\d+)?$/
: Cannot match decimals without integral part (.123)/^[+-]?(?:\d*\.)?\d+$/
: Cannot match the value with no decimal part (2.) and scientific notation (-2.e + 4)
Complete numerical regularity:
/^[+-]?(?:\d+\.?|\d*\.\d+)(?: e[+-]?\d+)?$/i
Use regularization to process values:
-
Numerical analysis
const reg = const reg = /[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?=px|\s|$)/gi; function execNumberList(str) { reg.lastIndex = 0; let exec = reg.exec(str); const result = []; while (exec) { result.push(parseFloat(exec[0])); exec = reg.exec(str); } return result; } console.log(execNumberList('1.0px .2px -3px +4e1px')); // [1, 0.2, -3, 40] console.log(execNumberList('+1.0px -0.2px 3e-1px')); // [1, -0.2, 0.3] console.log(execNumberList('1px 0')); // [1, 0] console.log(execNumberList('-1e+1px')); // [-10]
-
Value to currency format: that is, a comma is added to every thousandth
const reg = /(\d)(?=(\d{3})+(,|$))/g; function formatCurrency(str) { return str.replace(reg, '$1,'); } console.log(formatCurrency('1')); // 1 console.log(formatCurrency('123')); // 123 console.log(formatCurrency('12345678')); // 12,345,678
2.2 Scene two: regularity and color
How many ways to represent colors:
-
Hexadecimal notation
color: #rrggbb; color: #rgb; color: #rrggbbaa; color: #rgba;
const hex = '[0-9a-fA-F]'; const reg = new RegExp(`^(?:#${hex}{6}|#${hex}{8}|#${hex}{3,4})$`);
-
rgb / rgba notation
color: rgb(r, g, b); color: rgb(r%, g%, b%); color: rgba(r, g, b, a); color: rgba(r%, g%, b%, a); color: rgba(r, g, b, a%); color: rgba(r%, g%, b%, a%);
const num = '[+-]?(?:\\d*\\.)?\\d+(?:e[+-]?\\d+)?'; const comma = '\\s*,\\s*'; const reg = new RegExp(`rgba?\\(\\s*${num}(%?)(?:${comma}${num}\\1){2}(?:${comma}${num}%?)?\\s*\\)`);
-
other
/* hsl & hsla */ color: hsl(h, s%, l%); color: hsla(h, s%, l%, a); color: hsla(h, s%, l%, a%); /* keywords */ color: red; color: blue; /* …… */
Use regular processing colors:
- Hexadecimal color optimization
const hex = '[0-9a-z]'; const hexReg = new RegExp(`^#(?<r>${hex})\\k<r>(?<g>${hex})\\k<g>(?<b>${hex})\\k<b>(?<a>${hex}?)\\k<a>$`, 'i'); function shortenColor(str) { return str.replace(hexReg, '#$<r>$<g>$<b>$<a>'); } console.log(shortenColor('#336600')); // '#360' console.log(shortenColor('#19b955')); // '#19b955' console.log(shortenColor('#33660000')); // '#3600'
2.3 Scenario 3: Regular and URL
Parse the URL:
const protocol = '(?<protocol>https?:)';
const host = '(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)';
const path = '(?<pathname>(?:\\/[^/#?]+)*\\/?)';
const search = '(?<search>(?:\\?[^#]*)?)';
const hash = '(?<hash>(?:#.*)?)';
const reg = new RegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`);
function execURL(url) {
const result = reg.exec(url);
if (result) {
result.groups.port = result.groups.port || '';
return result.groups;
}
return {
protocol: '', host: '', hostname: '', port: '',
pathname: '', search: '', hash: '',
};
}
console.log(execURL('https://www.360.cn'));
console.log(execURL('http://localhost:8080/?#'));
console.log(execURL('https://image.so.com/view?q=360&src=srp#id=9e17bd&sn=0'));
console.log(execURL('this is not a url'));
console.log(execURL('https://www.360.cn'));
{
protocol: 'http:',
host: 'www.360.cn',
hostname: 'www.360.cn',
port: '',
pathname: '',
search: '',
hash: ''
}
console.log(execURL('http://localhost:8080/?#'));
{
protocol: 'http:',
host: 'localhost:8080',
hostname: 'localhost',
port: '8080',
pathname: '/',
search: '?',
hash: '#'
}
console.log(execURL('https://image.so.com/view?q=360&src=srp#id=9e17bd&sn=0'));
{
protocol: 'https:',
host: 'image.so.com',
hostname: 'image.so.com',
port: '',
pathname: '/view',
search: '?q=360&src=srp',
hash: '#id=9e17bd&sn=0'
}
console.log(execURL('this is not a url'));
{
protocol: '',
host: '',
hostname: '',
port: '',
pathname: '',
search: '',
hash: ''
}
Use regular to parse search and hash:
function execUrlParams(str) {
str = str.replace(/^[#?&]/, '');
const result = {};
if (!str) {
return result;
}
const reg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/y;
let exec = reg.exec(str);
while (exec) {
result[exec[1]] = exec[2];
exec = reg.exec(str);
}
return result;
}
console.log(execUrlParams('#')); // { }
console.log(execUrlParams('##')); // { '#': '' }
console.log(execUrlParams('?q=360&src=srp')); // { q: '360', src: 'srp' }
console.log(execUrlParams('test=a=b=c&&==&a=')); // { test: 'a=b=c', '': '=', a: '' }
3. Summary
How to use regular expressions?
- Clear demand
- Consider comprehensive
- Repeated testing