[regex] 正则 积累
名称 | 作用 |
---|---|
? |
{0,1} |
* |
{0,} |
+ |
{1,} |
. |
匹配任意单个字符,但是行结束符除外:\n \r \u2028 或 \u2029 。如果要匹配包括 \n 在内的任意字符,可以使用[\s\S] |
\d |
[0-9] |
\D |
[^0-9] |
\w |
[A-Za-z0-9_] |
\W |
[^A-Za-z0-9_] |
\s |
匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格, [\f\n\r\t\v\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004 \u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f \u3000] |
\S |
匹配一个非空白符,[^ \f\n\r\t\v\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004 \u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000] |
^ |
匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。 |
$ |
匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。 |
\b |
匹配一个零宽单词边界(zero-width word boundary),如一个字母与一个空格之间。例如,/\bno/ 匹配 "at noon" 中的 "no",/ly\b/ 匹配 "possibly yesterday." 中的 "ly"。 |
\B |
匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间。例如,/\Bon/ 匹配 "at noon" 中的 "on",/ye\B/ 匹配 "possibly yesterday." 中的 "ye"。 |
(x) |
匹配 x 并且捕获匹配项。 这被称为捕获括号(capturing parentheses)。例如,/(foo)/ 匹配且捕获 "foo bar." 中的 "foo"。被匹配的子字符串可以在结果数组的元素 [1], ..., [n] 中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到。捕获组(Capturing groups)有性能惩罚。如果不需再次访问被匹配的子字符串,最好使用非捕获括号(non-capturing parentheses)。 |
\n |
n 是一个正整数。一个反向引用(back reference),指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串。例如,/apple(,)\sorange\1/ 匹配 "apple, orange, cherry, peach." 中的 "apple,orange,"。 |
(?:x) |
匹配 x 不会捕获匹配项。这被称为非捕获括号(non-capturing parentheses)。匹配项不能够从结果数组的元素 [1], ..., [n] 或已被定义的 RegExp 对象的属性 $1, ..., $9 再次访问到。 |
x*? |
最小可能匹配 |
x+? |
例如,/".*?"/ 匹配 '"foo" "bar"' 中的 '"foo"',而 * 后面没有 ? 时匹配 '"foo" "bar"'。 |
x(?=y) |
仅匹配被y跟随的x。举个例子,/Jack(?=Sprat)/ ,如果"Jack"后面跟着sprat,则匹配之。`/Jack(?=Sprat |
x(?!y) |
仅匹配不被y跟随的x。举个例子,/\d+(?!\.)/ 只会匹配不被点. 跟随的数字。/\d+(?!\.)/.exec('3.141') 匹配"141",而不是"3.141" |
(?<=y)x |
x只有在y后面才匹配。'Benjamin Franklin is on the $100 €90 bill'.match(/(?<=\$)\d+/g) //["100"] |
(?<!y)x |
x只有不在y后面才匹配。'it’s is worth about €90 $100'.match(/(?<!\$)\d+/g) //["90", "00"] |
RegExp
RegExp 构造函数创建了一个正则表达式对象,用于将文本与一个模式匹配。
/pattern/flags
new RegExp(pattern [, flags])
RegExp(pattern [, flags])
pattern 正则表达式的文本。
flags 如果指定,标志可以具有以下值的任意组合:
- g 全局匹配;找到所有匹配,而不是在第一个匹配后停止
- i 忽略大小写
- m 多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
- u Unicode; 将模式视为Unicode序列点的序列
- y 粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。
- s dotAll模式,匹配任何字符(包括终止符 '\n')。
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;
支持传变量
/ab+c/i;
# 字面量
new RegExp('ab+c', 'i');
# 构造函数
new RegExp(/ab+c/, 'i');
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。
new RegExp("\\w+");
String.prototype.replace()
replace()
方法返回一个由替换值(replacement)替换一些或所有匹配的模式(pattern)后的新字符串。模式可以是一个字符串或者一个正则表达式, 替换值可以是一个字符串或者一个每次匹配都要调用的函数。
原字符串不会改变。
str.replace(regexp|substr, newSubStr|function)
替换字符串可以插入的特殊变量名:
变量名 | 代表的值
-
|-
$$ | 插入一个 "$"。
$& | 插入匹配(一般是括号里的匹配)的子串。
$` | 插入当前匹配的子串左边的内容。
$' | 插入当前匹配的子串右边的内容。
$n | 假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。
函数的参数:
变量名 | 代表的值 |
---|---|
match | 匹配的子串。(对应于上述的$&。) |
p1,p2, ... | 假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。) |
offset | 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么这个参数将是1) |
string | 被匹配的原字符串。 |
function replacer(match, p1, p2, p3, offset, string) {
// p1 is nondigits, p2 digits, and p3 non-alphanumerics
return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString); // abc - 12345 - #$*%
RegExp.prototype.test()
执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。
regexObj.test(str)
当想要知道一个模式是否存在于一个字符串中时,就可以使用 test()(类似于 String.prototype.search()
方法),差别在于test返回一个布尔值,而 search 返回索引(如果找到)或者-1(如果没找到);
如果正则表达式设置了全局标志g
,test()
的执行会改变正则表达式lastIndex
属性。连续的执行test()
方法,后续的执行将会从 lastIndex
处开始匹配字符串,(exec()
同样改变正则本身的 lastIndex属性值).
var regex = /foo/g;
// regex.lastIndex is at 0
regex.test('foo'); // true
// regex.lastIndex is now at 3
regex.test('foo'); // false
String.prototype.match()
match()
方法检索返回一个字符串匹配正则表达式的的结果。
str.match(regexp)
如果使用g
标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。
如果未使用g
标志,则仅返回第一个完整匹配及其相关的捕获组(Array)。
在这种情况下,返回的项目将具有如下所述的其他属性。
- groups: 一个捕获组数组 或 undefined(如果没有定义命名捕获组)。
- index: 匹配的结果的开始位置
- input: 搜索的字符串.
如果未找到匹配则为null。
不包含 g 标志,str.match()
将返回与 RegExp.exec()
. 相同的结果。
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
let a = str.match(/[A-E]/gi);
console.log(a);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
let b = str.match(/[A-E]/i);
console.log(b);
// 0: "A"
// groups: undefined
// index: 0
// input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// length: 1
如果你需要知道一个字符串是否与一个正则表达式匹配 RegExp ,可使用 test()
。
如果你只是需要第一个匹配结果,你也可以使用 RegExp.exec()
。
如果你想要获得捕获组,并且设置了全局标志,你需要用 RegExp.exec()
。
RegExp.prototype.exec()
exec()
方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。
如果你只是为了判断是否匹配(true或 false),可以使用 RegExp.test()
方法,或者 String.search()
str.search(regexp)
方法。
regexObj.exec(str)
当正则表达式使用 g
标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。
当你这样做时,查找将从正则表达式的 lastIndex 属性指定的位置开始。(test() 也会更新 lastIndex 属性)。
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
let aRe = /[A-E]/i;//不要对他进行循环,会陷入死循环
let a = aRe.exec(str);
console.log(a);
// 0: "A"
// groups: undefined
// index: 0
// input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// length: 1
let bRe = /[A-E]/ig;
let b = bRe.exec(str);
console.log(b);
// 0: "A"
// groups: undefined
// index: 0
// input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// length: 1
let bArr;
while (bArr = bRe.exec(str)) {
console.log(bArr);
console.log(bRe.lastIndex);
// ["B", index: 1, input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", groups: undefined]
// 0: "B"
// groups: undefined
// index: 1
// input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// length: 1
}
相关代码
.*?
.+?
let x = '<a href="xxx"></a><>';
let d = x.match(/<.*?>/g);
console.log(d);//["<a href="xxx">", "</a>", "<>"]
let e = x.match(/<.*>/g);
console.log(e);//["<a href="xxx"></a><>"]
let h = x.match(/<.+?>/g);
console.log(h);//["<a href="xxx">", "</a>"]
let i = x.match(/<.+>/g);
console.log(i);//["<a href="xxx"></a><>"]
let y = '"foo" "bar" ""';
let f = y.match(/".+?"/g);
console.log(f);//[""foo"", ""bar""]
let g = y.match(/".+"/g);
console.log(g);//[""foo" "bar" """]
匹配字符串中重复出现的内容
\n
\1 \2
的用法
正则表达式中的小括号()
是代表分组的意思。
如果再其后面出现\1
则是代表与第一个小括号中要匹配的内容相同。
\2
以此类推。
//这里会匹配得 aa bb cc 11 22 这种
/([a-zA-Z0-9])\1+/g
//这里会匹配 abba
/([a-z])([a-z])\2\1/
转换开始第N位到倒数第N位之间的字符
let str = `abcde1fg3h24ijklmn`
//let str = `abcdefghijklmn`;
let res = str.replace(/(.{3})(.*)(.{3})/, function (match, p1, p2, p3) {
return p1 + new Array(p2.length + 1).join('*') + p3;
})
//另一种
let res = str.replace(/(.{3}).*(.{3})/, '$1********$2');
match可用于统计出现次数
function derDieDas(wort) {
var vowels = wort.match(/[aeiouäöü]/gi).length;
if (vowels < 2) return `das ${wort}`;
if (vowels < 4) return `die ${wort}`;
return `der ${wort}`;
}
通过match判断a-z是否都出现过一次
function isPangram(string){
return (string.match(/([a-z])(?!.*\1)/ig) || []).length === 26;
}
字符串不需要转换成数组就能进行遍历
function DNAStrand(dna) {
return dna.replace(/./g, function(c) {
return DNAStrand.pairs[c]
})
}
实时给手机号打空格
也可以用在给钱加空格
'13012341234'.replace(/(^\d{3}|\d{4})(?=\d)/g,'$& ')
'13012341234'.replace(/\B(?=(\d{4})+$)/g,' ');
匹配某一个固定格式字符串后面的字符
let str = "a_b_2_d_1"
let result = str.match(/\B[a-z0-9]+/gi);
console.log(result); //["b", "2", "d", "1"]
let str = "a_b_2_d_1"
let re = /(?:_)([a-z0-9]+)/gi
let match
let result = []
while (match = re.exec(str)) {
result.push(match[1])
}
console.log(result)//["b", "2", "d", "1"]
获取url里的全部参数
let url = "https://api.test.com/search?name=xxx&age=yyy&sex=zzz";
let reg = /\?.+/;
//let result = reg.exec(url)[0];
let result = url.match(reg)[0];
let result = '';
let index = url.indexOf('?');
if (index > 0) {
result += url.substr(index);
}
console.log(result);
url参数解析方法
function analysisUrlParams(url, name) {
var reg = new RegExp('(^|&|/?)' + name + '=([^&]*)(&|$)', 'i');
var result = url.match(reg);
if (result) {
return decodeURIComponent(result[2]);
}
return '';
}
const q = {};
location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
console.log(q);
时间验证
/^([01]\d|2[0-3]):[0-5]\d$/.test('23:39')
互换字母顺序
var re = /(\w+)\s(\w+)/;
var str1 = "John Smith";
var newstr = str1.replace(re, "$2 $1");
console.log(newstr);//Smith John
其他
[x]
后边不能直接用{x}
,要用就要加括号。