学了好多遍的正则表达式,每次都是一看就会,一写就废。。。每次写代码要用到的时候半桶水大约只剩一滴水了,所以还是整理了下freeCodeCamp上的基础语法,以及项目中经常要用到的一些正则表达式。
一、基本语法
1、测试方法test
测试正则表达式的一种方法是使用.test()方法,test()方法会把你编写的正则表达式应用到一个字符串(及括号内的内容),如果你的匹配模式成功匹配到字符,则返回true,反之,返回false。
2、匹配单个文字字符串
let testStr = "freeCodeCamp";
// 用来测试你的字符串中是否包含"Code"字符串(区分大小写)
let testRegex = /Code/;
testRegex.test(testStr);
// Returns true
后台管理系统中经常会有对某个表单进行审核的功能,一般后台会返回给前端新建该表单时选择的审核人列表。前端这边需要判断目前登录的用户是否有审核权限,从而显示或隐藏审核按钮,这个时候就可以使用测试方法。
showAuditBtn(row) {
let reg = new RegExp(this.userInfo.userName)
// 若登录人的姓名包含在审核人列表中,则显示审核按钮,反之,则不显示
return reg.test(row.auditName)
},
3、匹配多个文字字符串
使用正则表达式/coding/,你可以在其他字符串中查找"coding"。
这对于搜索单个字符串非常有用,但限于一种匹配模式。
你可以使用|操作符(可以理解为'或')来匹配多个规则。此操作符匹配在它之前或之后的匹配模式。
例如,如果你想要匹配"yes"或"no",你需要的正则表达式是/yes|no/。你还可以匹配多个规则,这可以通过添加更多的匹配模式来实现。这些匹配模式将包含更多的|操作符来分隔它们,比如/yes|no|maybe/
完成正则表达式petRegex以匹配"dog"、"cat"、"bird"或者"fish"。
let petString = "James has a pet cat.";
let petString1 = "James has a pet .";
let petRegex = /dog|cat|bird|fish/;
let result = petRegex.test(petString); // Returns true
let result1 = petRegex.test(petString1); // Returns false
4、匹配时忽略大小写
上述说的匹配都是区分大小写的,如果需要忽略大小写的话可以使用i标志,将它附加到正则表达式之后来使用它。
编写正则表达式fccRegex以匹配"freeCodeCamp",忽略大小写
let myString = "freeCodeCamp";
// 不带标志时
let fccRegex = /FreeCodeCamp/;
// 带i标志时i
let fccRegex_i = /FreeCodeCamp/i;
let result = fccRegex.test(myString); // false
let result = fccRegex_i.test(myString); // true
5、提取匹配项match
.test()方法只是用来检查了一个匹配模式是否存在于字符串中,你还可以使用.match()方法来提取你找到的实际匹配项。
6、提取或搜寻一次匹配模式
"Hello, World!".match(/Hello/);
// Returns ["Hello"]
let ourStr = "Regular expressions";
let ourRegex = /expressions/;
ourStr.match(ourRegex);
// Returns ["expressions"]
let testStr = "Repeat, Repeat, Repeat";
let ourRegex = /Repeat/;
testStr.match(ourRegex);
// Returns ["Repeat"]
7、提取或搜寻多次匹配模式
若要多次搜寻或提取匹配模式,你可以使用g标志。
let testStr = "Repeat, repeat, Repeat";
// 全局匹配且区分大小写
let repeatRegex = /Repeat/g;
// 全局匹配且不区分大小写(正则表达式上可以有多个标志)
let repeatRegex_i = /Repeat/gi;
testStr.match(repeatRegex);
// Returns ["Repeat", "Repeat"]
testStr.match(repeatRegex_i);
// Returns ["Repeat","Repeat", "Repeat"]
8、用通配符.匹配任何内容
有时你不会(或不需要知道)知道匹配模式中的确切字符。如果要精确匹配到完整的单词,那出现一个拼写错误就会匹配不到,幸运的是,你可以使用通配符.来处理这种情况。
通配符将匹配任何一个字符。通配符也叫dot或period。你可以像使用正则表达式中任何其他字符一样使用通配符。
例如,如果你想匹配"hug"、"huh"、"hut"、"hum",你可以使用正则表达式/hu./匹配以上四个单词。
let humStr = "I'll hum a song";
let hugStr = "Bear hug";
let huRegex = /hu./;
humStr.match(huRegex); // Returns ["hum"]
hugStr.match(huRegex); // Returns ["hug"]
9、将单个字符与多种可能性匹配
上面的两种一种是精确匹配/literal/,一种是匹配所有/./。在这两种极端情况之间有一个平衡选项。
你可以使用字符集搜寻一定灵活性的文字匹配模式。字符集允许你通过把它们放在方括号([和])之间的方式来定义一组你需要匹配的字符串。
例如,你想要匹配"bag"、"big"和"bug",但是不想匹配"bog"。你可以创建正则表达式/b[aiu]g/来执行此操作。[aiu]是只匹配字符"a"、"i"或"u"的字符集。
let bigStr = "big";
let bagStr = "bag";
let bugStr = "bug";
let bogStr = "bog";
let bgRegex = /b[aiu]g/;
bigStr.match(bgRegex); // Returns ["big"]
bagStr.match(bgRegex); // Returns ["bag"]
bugStr.match(bgRegex); // Returns ["bug"]
bogStr.match(bgRegex); // Returns null
10、匹配字母表中的字母
若要匹配很多个字符,用上述方法一个个列出来的话则很麻烦,有一种写法可以让实现这个功能变的简短。
在字符集中,你可以使用连字符(-)来定义要匹配的字符范围。
例如要匹配小写字母a到e,你可以使用[a-e]
let catStr = "cat";
let batStr = "bat";
let matStr = "mat";
let bgRegex = /[a-e]at/;
catStr.match(bgRegex); // Returns ["cat"]
batStr.match(bgRegex); // Returns ["bat"]
matStr.match(bgRegex); // Returns null
11、匹配字母表中的数字和字母
使用连字符(-)匹配字符范围并不限于字母。它还可以匹配一系列数字。
例如,/[0-5]/匹配0和5之间的任意数字,包含0和5。
此外,还可以在单个字符集中组合一系列字母和数字。
let jennyStr = "Jenny8675309";
let myRegex = /[a-z0-9]/ig;
// matches all letters and numbers in jennyStr
jennyStr.match(myRegex);
12、匹配单个未指定的字符
到目前为止,你已创建了一个你想要匹配的字符集合,但你也可以创建一个你不想匹配的字符集合。这些类型的字符集称为否定字符集。
要创建否定字符集,你需要在开始括号后面和不想匹配的字符前面放置插入字符(即^)。
例如,/[^aeiou]/gi匹配所有非元音字符。注意,字符.、!、[、@、/和空白字符等也会被匹配,该否定字符集仅排除元音字符。
创建一个匹配所有非数字或元音字符的正则表达式。请记得在正则表达式中包含恰当的标志。
let quoteSample = "3 blind mice.";
let myRegex = /[^0-9|aeiou]/gi;
let result = quoteSample.match(myRegex);
// Returns [" ","b","l","n","d"," ","m","c","e","."]
13、匹配出现一次或多次的字符
有时,你需要匹配出现一次或者连续多次的字符(或字符组)。这意味着它至少出现一次,并且可能重复出现。
你可以使用+符合来检查情况是否如此。记住,字符或匹配模式必须一个接一个地连续出现。
例如,/a+/g会在"abc"中匹配到一个匹配项,并且返回["a"]。因为+的存在,它也会在"aabc"中匹配到一个匹配项,然后返回["aa"]。
如果它是检查字符串"abab",它将匹配到两个匹配项并且返回["a", "a"],因为a字符不连续,在它们之间有一个b字符。最后,因为在字符串"bcd"中没有"a",因此找不到匹配项。
在字符串"Mississippi"中匹配到出现一次或多次的字母s的匹配项。编写一个使用+符号的正则表达式。
let difficultSpelling = "Mississippi";
let myRegex = /s+/g;
let result = difficultSpelling.match(myRegex);
// Returns ["ss","ss"]
14、匹配出现零次或多次的字符
执行该操作的字符叫做asterisk或star,即*。
let soccerWord = "gooooooooal!";
let gPhrase = "gut feeling";
let oPhrase = "over the moon";
let goRegex = /go*/;
soccerWord.match(goRegex); // Returns ["goooooooo"]
gPhrase.match(goRegex); // Returns ["g"]
oPhrase.match(goRegex); // Returns null
创建一个变量为chewieRegex的正则表达式,使用*符号在chewieQuote中匹配"A"及其之后出现的零个或多个"a"。你的正则表达式不需要使用修饰符,也不需要匹配引号。
let chewieQuote = "Aaaaaaaaaaaaaaaarrrgh!";
let chewieRegex = /Aa*/;
let result = chewieQuote.match(chewieRegex);
// Returns ["Aaaaaaaaaaaaaaaa"]
15、用惰性匹配来查找字符
在正则表达式中,贪婪匹配会匹配搭配符合正则表达式匹配模式的字符串的最长可能部分,并将其作为匹配项返回。另一种方案称为懒惰匹配,它会匹配到满足正则表达式的字符串的最小可能部分。
你可以将正则表达式/t[a-z]*i/应用于字符串"titanic"。这个正则表达式是一个以t开始,以i结束,并且中间有一些字母的匹配模式。
正则表达式默认是贪婪匹配,因此匹配返回为["titani"]。它会匹配到适合该匹配模式的最大子字符串。
但是,你可以使用?字符来将其变成懒惰匹配。调整后的正则表达式/t[a-z]*?i/匹配字符串"titanic"返回["ti"]。
修复正则表达式/<.*>/,让它返回 HTML 标签<h1>,而不是文本"<h1>Winter is coming</h1>"。请记得在正则表达式中使用通配符.来匹配任意字符。
let text = "<h1>Winter is coming</h1>";
let myRegex = /<h1.*?>/;
let result = text.match(myRegex);
// Returns ["<h1>"]
16、测试题:在狩猎中找到一个或多个罪犯
一群罪犯逃出监狱逃跑,但你不知道有多少人。但是,你知道他们和其他人在一起时会保持紧密联系。你有责任立刻找到所有的罪犯。
这里有一个示例来回顾如何做到这一点:
当字母z在一行中出现一次或连续多次时,正则表达式/z+/会匹配到它。它会在以下所有字符串中找到匹配项:
"z"
"zzzzzz"
"ABCzzzz"
"zzzzABC"
"abczzzzzzzzzzzzzzzzzzzzzabc"
但是它不会在以下字符串中找到匹配项,因为它们中没有字母z:
""
"ABC"
"abcabc"
编写一个贪婪正则表达式,在一组其他人中匹配到一个或多个罪犯。罪犯由大写字母C表示。
// example crowd gathering
let crowd = 'P1P2P3P4P5P6CCCP7P8P9';
let reCriminals = /C+/;
let matchedCriminals = crowd.match(reCriminals);
console.log(matchedCriminals); // ["CCC"]
17、匹配字符串的开头
使用字符集中插入符合(^)可以创建一个否定字符集,形如[^thingsThatWillNotBeMatched]。在字符集之外,插入符合用于字符串的开头搜寻匹配模式。
let firstString = "Ricky is first and can be found.";
let firstRegex = /^Ricky/;
firstRegex.test(firstString);
// Returns true
let notFirst = "You can't find Ricky now.";
firstRegex.test(notFirst);
// Returns false
18、匹配字符串的末尾
使用正则表达式的美元符合$来搜寻字符串的结尾
let theEnding = "This is a never ending story";
let storyRegex = /story$/;
storyRegex.test(theEnding);
// Returns true
let noEnding = "Sometimes a story will have to end";
storyRegex.test(noEnding);
// Returns false
19、匹配所有的字母和数字
使用字符类,你可以使用[a-z]搜寻字母表中的所有字母。这种字符类是很常见的,它有一个缩写,但这个缩写也包含额外的字符。
JavaScript 中与字母表匹配的最接近的字符类是\w,这个缩写等同于[A-Za-z0-9_]。它不仅可以匹配大小写字母和数字,注意,它还会匹配下划线字符(_)。
let longHand = /[A-Za-z0-9_]+/;
let shortHand = /\w+/;
let numbers = "42";
let varNames = "important_var";
longHand.test(numbers); // Returns true
shortHand.test(numbers); // Returns true
longHand.test(varNames); // Returns true
shortHand.test(varNames); // Returns true
使用缩写\w来计算所有引号中字母和数字字符的数量。
let quoteSample = "The five boxing wizards jump quickly.";
let alphabetRegexV2 = /\w/g;
let result = quoteSample.match(alphabetRegexV2).length; //31
20、匹配除了字母和数字的所有符号
你可以使用\W搜寻和\w相反的匹配模式。注意,相反匹配模式使用大写字母。此缩写与[^A-Za-z0-9_]是一样的。
let shortHand = /\W/;
let numbers = "42%";
let sentence = "Coding!";
numbers.match(shortHand); // Returns ["%"]
sentence.match(shortHand); // Returns ["!"]
使用缩写\W来计算不同引号和字符串中非字母数字字符的数量。
let quoteSample = "The five boxing wizards jump quickly.";
let nonAlphabetRegex = /\W/g;
let result = quoteSample.match(nonAlphabetRegex).length; // 6
21、匹配所有数字
查找数字字符的缩写是\d,注意是小写的d。这等同于字符类[0-9],它查找0到9之间任意数字的单个字符。
使用缩写\d来计算电影标题中有多少个数字。书面数字("six"而不是6)不计算在内。
let numString = "Your sandwich will be $5.00";
let numRegex = /\d/g;
let result = numString.match(numRegex).length; // 1
22、匹配所有非数字
查找非数字字符的缩写是\D。这等同于字符串[^0-9],它查找不是 0 - 9 之间数字的单个字符。
使用非数字缩写\D来计算电影标题中有多少非数字。
let numString = "21 Jump Street";
let noNumRegex = /\D/g; //
let result = numString.match(noNumRegex).length; // 12
23、测试题:限制可能的用户名
你需要检查数据库中的所有用户名。以下是用户在创建用户名时必须遵守的一些简单规则。
- 用户名中的数字必须在最后,且数字可以有零个或多个。
- 用户名字母可以是小写字母和大写字母。
- 用户名长度必须至少为两个字符。两位用户名只能使用字母。
修改正则表达式userCheck以适合上面列出的约束。
let username = "JackOfAllTrades";
let username1 = "J";
<!--
正则一
[a-zA-Z]:大写字母或者小写字母;
{2,}:至少2位;
\d*:数字有零个或多个;
$:字符串末尾
-->
let userCheck = /[a-zA-Z]{2,}\d*$/;
<!--
正则二
^:字符串开头;
[a-z]:小写字母;
[0-9][0-9]+:至少2位数字;
|:或;
[a-z]+:至少一位小写字母;
\d*:零个或多个数字;
$:字符串结尾;
i:不区分大小写
-->
let userCheck2 = /^[a-z]([0-9][0-9]+|[a-z]+\d*)$/i;
<!--
正则三
^:字符串开头;
[a-z]:小写字母;
[0-9]{2,}:至少2位数字;
|:或;
[a-z]+:至少一位小写字母;
\d*:零个或多个数字;
$:字符串结尾;
i:不区分大小写
-->
let userCheck3 = /^[a-z]([0-9]{2,}|[a-z]+\d*)$/i;
let result = userCheck.test(username); // true
let result1 = userCheck.test(username1); // false
24、匹配空白字符
你可以使用\s搜寻空格,其中s是小写。此匹配模式不仅匹配空格,还匹配回车符、制表符、换页符和换行符,你可以将其视为与[\r\t\f\n\v]类似。
let whiteSpace = "Whitespace. Whitespace everywhere!"
let spaceRegex = /\s/g;
whiteSpace.match(spaceRegex);
// Returns [" ", " "]
25、匹配非空白字符
使用\S搜寻非空白字符,其中S是大写。此匹配模式将不匹配空格、回车符、制表符、换页符和换行符。你可以认为这类似于字符类[^\r\t\f\n\v]。
let whiteSpace = "Whitespace. Whitespace everywhere!"
let nonSpaceRegex = /\S/g;
whiteSpace.match(nonSpaceRegex).length; // Returns 32
26、指定匹配的上限和下限
回想一下,你使用加号+查找一个或多个字符,使用星号*查找零个或多个字符。这些都很方便,但有时你需要匹配一定范围的匹配模式。
你可以使用数量说明符指定匹配模式的上下限。数量说明符与花括号({和})一起使用。你可以在花括号之间放两个数字,这两个数字代表匹配模式的上限和下限。
例如,要在字符串"ah"中匹配仅出现3到5次的字母a,你的正则表达式应为/a{3,5}h/。
let A4 = "aaaah";
let A2 = "aah";
let multipleA = /a{3,5}h/;
multipleA.test(A4); // Returns true
multipleA.test(A2); // Returns false
修改正则表达式ohRegex以匹配在"Oh no"中仅出现3到6次的字母h。
let ohStr = "Ohhh no";
let ohStr = "Ohhhhhhh no"
let ohRegex = /Oh{3,6}\sno/;
let result = ohRegex.test(ohStr); // true
let result1 = ohRegex1.test(ohStr); // false
27、只指定匹配的下限
你可以使用带有花括号的数量说明符来指定匹配模式的上下限。但有时候你只想指定匹配模式的下限而不需要指定上限。
为此,在第一个数字后面跟一个逗号即可。
例如,要匹配至少出现3次字母a的字符串"hah",你的正则表达式应该是/ha{3,}h/。
let A4 = "haaaah";
let A2 = "haah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleA = /ha{3,}h/;
multipleA.test(A4); // Returns true
multipleA.test(A2); // Returns false
multipleA.test(A100); // Returns true
28、指定匹配的确切数量
你可以使用带有花括号的数量说明符来指定匹配模式的上下限。但有时你只需要特定数量的匹配。
要指定一定数量的匹配模式,只需在大括号之间放置一个数字。
例如,要只匹配字母a出现3次的单词"hah",你的正则表达式应为/ha{3}h/。
let A4 = "haaaah";
let A3 = "haaah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleHA = /a{3}h/;
multipleHA.test(A4); // Returns false
multipleHA.test(A3); // Returns true
multipleHA.test(A100); // Returns false
29、检查全部或无
有时,你想要搜寻的匹配模式可能有不确定是否存在的部分。尽管如此,你还是想检查它们。
为此,你可以使用问号?指定可能存在的元素。这将检查前面的零个或一个元素。你可以将此符号视为前面的元素是可选的。
例如,美式英语和英式英语略有不同,你可以使用问号来匹配两种拼写。
let american = "color";
let british = "colour";
let rainbowRegex= /colou?r/;
rainbowRegex.test(american); // Returns true
rainbowRegex.test(british); // Returns true
30、正向先行断言和负向先行断言
先行断言是告诉 JavaScript 在字符串中向前查找的匹配模式。当你想要在同一个字符串上搜寻多个匹配模式时,这可能非常有用。
有两种先行断言:正向先行断言和负向先行断言。
正向先行断言会查看并确保搜索匹配模式中的元素存在,但实际上并不匹配。正向先行断言的用法是(?=...),其中...就是需要存在但不会被匹配的部分。
另一方面,负向先行断言会查看并确保搜索匹配模式中的元素不存在。负向先行断言的用法是(?!...),其中...是你希望不存在的匹配模式。如果负向先行断言部分不存在,将返回匹配模式的其余部分。
尽管先行断言有点儿令人困惑,但是这些示例会有所帮助。
let quit = "qu";
let noquit = "qt";
// 匹配后面有u的q
let quRegex= /q(?=u)/;
// 匹配后面没有u的q
let qRegex = /q(?!u)/;
quit.match(quRegex); // Returns ["q"]
noquit.match(qRegex); // Returns ["q"]
先行断言的更实际用途是检查一个字符串中的两个或更多匹配模式。这里有一个简单的密码检查器,密码规则是 3 到 6 个字符且至少包含一个数字:
let password = "abc123";
let checkPass = /(?=\w{3,6})(?=\D*\d)/;
checkPass.test(password); // Returns true
在正则表达式pwRegex中使用先行断言以匹配至少5个字符且有两个连续数字的密码。
let sampleWord = "astronaut";
<!--
(?=\w{5}):匹配5个字符串
(?=\D*\d{2}):匹配有两个连续数字,数字前面0个或多个非数字的字符串
两组匹配出来的index要相等
-->
var pwRegex = /(?=\w{5})(?=\D*\d{2})/;
let result = pwRegex.test(sampleWord); //false
最开始我的答案是下面这样的,琢磨了好久才知道原因
let sampleWord = "dd22d";
let sampleWord1 = "dd22ddd"
var pwRegex = /(?=\w{5})(?=\d{2})/;
<!--
(?=\w{5})匹配到的index是0
(?=\d{2})匹配到的index是2
两组匹配出来的index不相等,所以为false
-->
let result = pwRegex.test(sampleWord); //false
<!--
(?=\w{5})匹配到的index是0,1,2
(?=\d{2})匹配到的index是2
两组有相等的index为2,所以为true
-->
let result1 = pwRegex.test(sampleWord1); //true
31、使用捕获组重用模式
一些你所搜寻的匹配模式会在字符串中出现多次,手动重复该正则表达式太浪费了。有一种更好的方法可以指定何时在字符串中会有多个重复的子字符串。
你可以使用捕获组搜寻重复的子字符串。括号(和)可以用来匹配重复的子字符串。你只需要把重复匹配模式的正则表达式放在括号中即可。
要指定重复字符串将出现的位置,可以使用反斜杠(\)后接一个数字。这个数字从 1 开始,随着你使用的每个捕获组的增加而增加。这里有一个示例,\1可以匹配第一个组。
下面的示例匹配任意两个被空格分割的单词:
let repeatStr = "regex regex";
let repeatRegex = /(\w+)\s\1/;
repeatRegex.test(repeatStr); // Returns true
repeatStr.match(repeatRegex); // Returns ["regex regex", "regex"]
在正则表达式reRegex中使用捕获组,以匹配在字符串中仅重复三次的数字,每一个都由空格分隔。
let repeatNum = "42 42 42";
let reRegex = /^(\d+)\s\1\s\1$/;
let reRegex1 = /^(\d+)(\s)\1\2\1$/;
let result = reRegex.test(repeatNum); // true
let result1 = reRegex1.test(repeatNum); // true
32、使用捕获组搜索和替换
搜索功能是很有用的。但是,当你的搜索也执行更改(或替换)匹配文本的操作时,搜索功能就会显得更加强大。
可以使用字符串上.replace()方法来搜索并替换字符串中的文本。.replace()的输入首先是你想要搜索的正则表达式匹配模式,第二个参数是用于替换匹配的字符串或用于执行某些操作的函数。
let wrongText = "The sky is silver.";
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue");
// Returns "The sky is blue."
你还可以使用美元符号($)访问替换字符串中的捕获组。
"Code Camp".replace(/(\w+)\s(\w+)/, '$2 $1');
// Returns "Camp Code"
33、测试题:删除开头和结尾的空白
有时字符串周围存在的空白字符并不是必需的。字符串的典型处理是删除字符串开头和结尾处的空格。
编写一个正则表达式并使用适当的字符串方法删除字符串开头和结尾的空格。
let hello = " Hello, World! ";
let wsRegex = /^\s+|\s+$/g;
let result = hello.replace(wsRegex, "");
二、速记表
| 字符 | 描述 |
|---|---|
| \ | 正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成+。正则表达式中,需要反斜杠转义的,一共有12个字符:^、.、[、$、(、)、|、*、+、?、{和\。 |
| 匹配输入字符串的开始位置 | |
| $ | 匹配输入字符串的结束位置 |
| \b | 匹配一个单词边界(boundary),也就是指单词和空格间的位置,包括开头和结尾 |
| \B | 匹配非单词边界 |
| (?:p) | 匹配到p但是不会捕获这部分内容,后续无法使用$1这种方法访问到匹配的内容 |
| (?=p) | 匹配后面是p的位置 |
| (?!p) | 匹配后面不是p的位置 |
| (?<=p) | 匹配前面是p的位置 |
| (?<!p) | 匹配前面不是p的位置 |
| ? | 匹配前面的子表达式零次或一次 |
| * | 匹配前面的子表达式零次或多次 |
| + | 匹配前面的子表达式一次或多次 |
| {n} | n 是一个非负整数。匹配确定的 n 次。 |
| {n,} | n 是一个非负整数。至少匹配n 次。 |
| {n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
| x|y | 匹配 x 或 y |
| [xyz] | 字符集合。匹配所包含的任意一个字符 |
| [^xyz] | 负值字符集合。匹配未包含的任意字符。 |
| [a-z] | 字符范围。匹配指定范围内的任意字符。 |
| [^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。 |
| \d | 匹配一个数字字符。等价于 [0-9] |
| \D | 匹配一个非数字字符。等价于 [^0-9] |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] |
| \S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
| \w | 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。 |
| \W | 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。 |
| . | 匹配除换行符 \n 之外的任何单字符 |
三、运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
| 运算符 | 描述 | |
|---|---|---|
| \ | 转义符 | |
| (), (?:), (?=), [] | 圆括号和方括号 | |
| *, +, ?, {n}, {n,}, {n,m} | 限定符 | |
| ^, $, \任何元字符、任何字符 | 定位点和序列(即:位置和顺序) | |
| | | 替换,"或"操作 | |
| 字符具有高于替换运算符的优先级,使得"m | food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m | f)ood"。 |
四、常用的正则表达式
1、校验数字的表达式
- 数字:
^[0-9]+$或^\d+$ - n位的数字:
^\d{n}$ - 至少n位的数字:
^\d{n,}$ - m-n位的数字:
^\d{m,n}$ - 零和非零开头的数字:
^(0|[1-9][0-9]*)$ - 最多带两位小数的正数:
^([1-9][0-9]*)+(\.[0-9]{1,2})?$ - 最多带两位小数的正数或负数:
^(\-)?\d+(\.\d{1,2})?$ - 正数、负数、和小数:
^(\-|\+)?\d+(\.\d+)?$ - 整数:
^-?[1-9]\d*$ - 正整数:
^[1-9]\d*$或^\+?[1-9][0-9]*$ - 负整数:
^-[1-9][0-9]*$或^-[1-9]\d*$ - 非负整数:
^\d+$或^[1-9]\d*|0$ - 非正整数:
^-[1-9]\d*|0$或^((-\d+)|(0+))$
2、校验字符的表达式
- 汉字:
^[\u4e00-\u9fa5]{0,}$ - 英文和数字:
^[A-Za-z0-9]+$或^[A-Za-z0-9]{4,40}$ - 长度为3-20的所有字符:
^.{3,20}$ - 由26个英文字母组成的字符串:
^[A-Za-z]+$ - 由26个大写英文字母组成的字符串:
^[A-Z]+$ - 由26个小写英文字母组成的字符串:
^[a-z]+$ - 由数字和26个英文字母组成的字符串:
^[A-Za-z0-9]+$ - 由数字、26个英文字母或者下划线组成的字符串:
^\w+$或^\w{3,20}$ - 中文、英文、数字包括下划线:
^[\u4E00-\u9FA5A-Za-z0-9_]+$ - 中文、英文、数字但不包括下划线等符号:
^[\u4E00-\u9FA5A-Za-z0-9]+$或^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ - 可以输入含有
^%&',;=?$\"等字符:[^%&',;=?$\x22]+ - 禁止输入含有
~的字符:[^~\x22]+
3、实例
校验金额,精确到小数后两位小数
function checkMoney(money){
return /^\d+(\.\d{1,2})?$/.test(money)
}
校验带有千位符的金额,精确到小数后两位小数
function checkMoney(money){
return /^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$/.test(money)
}
检验数量
function checkCount(count){
return /^[1-9]\d*$/.test(count)
}
校验数字
function checkNum(num){
return /^\d+$/.test(num)
}
校验版本号,形如1.1.1
function checkVersion(version){
return /^\d+(\.\d+)*$/.test(version)
}
校验0-1之间的浮点数,精确到小数点后两位
function checkFloat(float){
return /^(1|0(\.\d{1,2})?)$/.test(float)
}
input框输入时限制只能为数字
function handleInput(val){
return val.replace(/[^\d.]/g, '')
}
input框输入时限制最多只能输入n位字符
function handleInput(val,n){
return val.replace(/^(.{n})./g, '$1'/)
}
input框输入时限制最多只能有两位小数
function handleInput(val,n){
return val.replace(/^(\-)*(\d*)\.(\d\d).*$/, '$1$2.$3')
}
千位符转换
function change(num){
let val = num + ''
let reg = val.indexOf('.') > -1 ? /(\d{1,3})(?=(\d{3})+(?:\.))/g : /(\d{1,3})(?=(\d{3})+(?:$))/g
return val.replace(reg,'$1,')
}
校验手机号码
function checkPhone(phone){
return /^1[3456789]\d{9}$/.test(phone)
}
校验座机号码
function checkPhone(phone){
return /^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$/.test(phone)
}
校验身份证号码
function checkIDCard(IDCard){
//身份证正则表达式(15位) /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
//身份证正则表达式(18位) isIDCard2=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
//身份证正则合并:(^\d{15}$)|(^\d{17}([0-9]|X)$)
return /(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(IDCard)
}
校验银行卡号
function checkCard(card){
return /^(\d{16}|\d{19}|\d{17}|\d{18})$/.test(card)
}
匹配日期,格式如2020-07-11
function checkDate(date){
return /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/.test(data)
}
匹配日期兼容格式,匹配2020-07-11、2020/07/11、2020.07.11三种格式
function checkDate(date){
return /^\d{4}(-|\/|\.)\d{2}\1\d{2}$/.test(data)
}
匹配时间,格式如23:59:59
function checkTime(time){
return /^([01][0-9]|[2][0-3]):[0-5][0-9]:[0-5][0-9]$/.test(time)
}
日期格式化,将2020-07-11转换为2020年7月11日
function formatDate(date){
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var result = date.replace(regex, "$1年$2月$3日");
return result
}
去掉字符串空格
function trim(string){
// 方法一 return str.replace(/^\s+|\s+$/g, '');
//方法二
return str.replace(/^\s*(.*?)\s*$/g, "$1");
}
校验邮箱
function checkEmail(email){
return /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(email)
}
校验腾讯qq号码
function checkQQ(qq){
return /^[1-9][0-9]{4,}$/.test(qq)
}
校验邮政编码
function checkCode(code){
return /^[1-9]\d{5}(?!\d)$/.test(code)
}
校验IP地址
function checkIP(ip){
return /^((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))$/.test(ip)
}
校验url
function checkUrl(url){
return /^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$/.test(url)
}
将单词的首字母变成大写
function titleize(str) {
return str.toLowerCase().replace(/(?:^|\s)\w/g, function(c) {
return c.toUpperCase();
});
}
将单词转为驼峰形式
function camelize(str) {
return str.replace(/[-_\s]+(.)?/g, function(match, c) {
return c ? c.toUpperCase() : '';
});
}
将单词中划线化
function dasherize(str) {
return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
}
五、常用正则编辑调试器
1、Debuggex
2、Regulex
3、Rubular
参考地址:
1、freeCodeCamp
2、JavaScript 正则表达式