2. 如何编写javascript
我只是文档搬运工,总结得很差,不免疏漏,如有错误请帮我指出,谢谢。ide
使用字面量定义的任何正则表达式均可以使用构造函数来构建函数
正则表达式是构成搜索模式(search pattern)的字符序列,匹配字符串中字符组合的模式。至关因而一个描述或者一个检索规则,针对你想要操做的内容。post
在JS中 RegExp 是对象,有 test 方法和 exec 方法,同时还有字符串的 match、replace、search、split、matchAll 方法可用。可经过 正则表达式字面量 直接建立或者 new RegExp 对象。性能
mdn中说道:脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用字面量可得到更好的性能。在脚本运行的过程当中,用构造函数建立的正则表达式会被编译。若正则表达式发生该改变,或者须要从用户输入等来源中动态的产生,就须要使用构造函数来建立正则表达式。在须要改变正则表达式是可使用compile从新编译。
为何要从新编译呢?我发现测试时即使不从新编译输出结果也是同样的,我在掘金找到一份回答:https://juejin.im/post/5b6adc... 也许有用 大意为:若是指定的正则表达式须要屡次重复使用,那么编译正则表达式将会提升代码的执行效率,不过若是仅仅执行一次或者少数几回,那么将不会有明显的效果,compile提升了正则表达式的适应性!测试
格式:/pattern/flags;
直接使用 /str/
便可
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
const text = 'A quick fox'; const regexpLastWord = /\w+$/; console.log(text.match(regexpLastWord)); // expected output: Array ["fox"] const regexpWords = /\b\w+\b/g; // \b表单词边界 console.log(text.match(regexpWords)); // expected output: Array ["A", "quick", "fox"] const regexpFoxQuality = /\w+(?= fox)/; // 匹配前面的\w+仅当\w+后面跟着fox时,这种叫作先行断言。 console.log(text.match(regexpFoxQuality)); // expected output: Array ["quick"]
Characters | Meaning |
---|---|
^ |
Matches the beginning of input |
$ |
Matches the end of input |
\b |
Matches a word boundary |
\B |
Matches a non-word boundary |
x(?=y) |
Matches "x" only if "x" is followed by "y" |
x(?!y) |
Matches "x" only if "x" is not followed by "y" |
(?<=y)x |
Matches "x" only if "x" is preceded by "y" |
(?<!y)x |
Matches "x" only if "x" is not preceded by "y" |
attention:(different meaning in the start of group)
Characters | Meaning | |
---|---|---|
`x | y` | Matches either "x" or "y" |
[xyz] [a-c] |
A character set. | |
[^xyz] [^a-c] |
A negated or complemented character set | |
(x) |
Matches x and remembers the match | |
\n |
Where "n" is a positive integer | |
(?<Name>x) |
Named capturing group | |
(?:x) |
Non-capturing group |
attention:(?<Name>x)
Matches "x" and stores it on the groups property of the returned matches under the name specified by<Name>
表示行和单词的开始和结尾。
区分不一样类型的字符,例如区分字母和数字。
表示表达式字符的分组和范围。
表示匹配的字符或表达式的数量。
基于 unicode 字符属性区分字符。例如大写和小写字母、数学符号和标点。
我看了 w3school.com.cn
的解释和 MDN 的解释,对比一下,建议看 MDN 正则表达式中特殊字符的含义。
量词 | 描述 | |
---|---|---|
n+ |
匹配前面的模式 n 1 次或屡次 | |
n* |
匹配前面的模式 n 0 或屡次 | |
n? |
匹配前面的模式 n 0 或 1 次 | |
n{X} |
x 是一个正整数。前面的模式 n 连续出现 x 次时匹配 | |
n{X,Y} |
匹配包含 X 至 Y 个 n 的序列的字符串。 | |
n{X,} |
匹配包含至少 X 个 n 的序列的字符串。 | |
n$ |
匹配任何结尾为 n 的字符串。 | |
^n |
匹配任何开头为 n 的字符串。 | |
?=n |
匹配任何其后紧接指定字符串 n 的字符串。 | |
?!n |
匹配任何其后没有紧接指定字符串 n 的字符串。 | |
`x\ | y` | 匹配 x 或 y |
var re = /pattern/flags;
or var re = new RegExp('pattern', 'flags');
flag | 意义 | 对应的属性 |
---|---|---|
i | 不区分大小写 | RegExp.prototype.global |
g | 全局搜索 | RegExp.prototype.ignoreCase |
m | 多行搜索 | RegExp.prototype.multiline |
s | 容许 . 匹配换行符 (在 ES2018 添加,Firefox不支持) |
RegExp.prototype.dotAll |
u | 使用unicode码的模式进行匹配 | RegExp.prototype.unicod |
y | 执行 粘性 搜索,匹配从目标字符串的当前位置开始,可使用y标志 | RegExp.prototype.sticky |
exec()的状况下,正则表达式是 拥有该方法 的正则表达式,其中字符串是参数;在.match()的状况下,字符串类(or data type)拥有该方法,而正则表达式只是一个参数。对比str.match(reg)
与reg.exec(str)
, 'g'
标志与exec()
方法一块儿使用由于lastIndex参数会迭代进行,这在后面讲exec方法有详细介绍。
m标志用于指定多行输入字符串应该被视为多个行。若是使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。
var reg = new RegExp("^.", "gm"); var str = "hui \nhello \nfuck!"; console.log(str.match(reg)); //(3) ["h", "h", "f"]
var names = "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand "; var output = ["---------- Original String\n", names + "\n"]; // 此时output = ["---------- Original String↵", "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ↵"] var pattern = /\s*;\s*/; var nameList = names.split(pattern); // 此时nameList = ["Orange Trump", "Fred Barney", "Helen Rigby", "Bill Abel", "Chris Hand "] pattern = /(\w+)\s+(\w+)/; var bySurnameList = []; output.push("---------- After Split by Regular Expression"); // 此时output = ["---------- Original String↵", "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ↵", "---------- After Split by Regular Expression"] var i, len; for (i = 0, len = nameList.length; i < len; i++) { output.push(nameList[i]); bySurnameList[i] = nameList[i].replace(pattern, "$2, $1"); console.log("xixixi:" + bySurnameList[i]); } // 输出新的数组 output.push("---------- Names Reversed"); for (i = 0, len = bySurnameList.length; i < len; i++) { output.push(bySurnameList[i]); } // 根据姓来排序,而后输出排序后的数组。 bySurnameList.sort(); output.push("---------- Sorted"); for (i = 0, len = bySurnameList.length; i < len; i++) { output.push(bySurnameList[i]); } output.push("---------- End"); console.log(output.join("\n"));
RegExpObject.compile(regexp,modifier)
用于在脚本执行过程当中编译正则表达式,也可用于改变或从新编译正则表达式。modifier只有i、g
var str = "Every man in the world! Every woman on earth!"; console.log(str); patt = /man/g; str2 = str.replace(patt, "person"); console.log(str2); console.log(patt); patt = /(wo)?man/g; console.log(patt); patt.compile(patt); //改变正则表达式以后从新编译 // 为何要从新编译呢?我发现测试时即使不从新编译输出结果也是同样的 // 我在掘金找到一份回答:https://juejin.im/post/5b6adc7ee51d4534b8587560#heading-22 // 大意为:若是指定的正则表达式须要屡次重复使用,那么编译正则表达式将会提升代码的执行效率,不过若是仅仅执行一次或者少数几回,那么将不会有明显的效果,compile提升了正则表达式的适应性! console.log(patt); str2 = str.replace(patt, "person"); console.log(str2);
RegExpObject.exec(string)
经过模式搜索字符串并返回已找到的文本,返回的是一个数组,但即便字符串中有多个匹配的文本时也只会返回第一个匹配到的结果。
exec更加灵活也更加复杂,若是 exec() 找到了匹配的文本,则返回一个结果数组。不然,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(若是有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(若是有的话),以此类推。除了数组元素和 length 属性以外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。咱们能够看得出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。
可是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置成匹配到的文本中的最后一个字符的下一个位置,在下面的例子中也就是每次匹配到的hui中的i字符对应的下一个位置。可知经过反复调用 exec() 方法可遍历字符串中的全部匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
var reg = new RegExp(/hui/ig); var str = 'hui hui hui Like Summer'; console.log(reg.lastIndex); //0 console.log(reg.exec(str));//["hui", index: 0, input: "hui hui hui Like Summer", groups: undefined] // 匹配的的文本的最后一个字符的下一位即2的下一位为3 console.log(reg.lastIndex); //3 console.log(reg.exec(str));//["hui", index: 4, input: "hui hui hui Like Summer", groups: undefined] console.log(reg.lastIndex); //7 console.log(reg.exec(str));//["hui", index: 8, input: "hui hui hui Like Summer", groups: undefined] console.log(reg.lastIndex); //11 console.log(reg.exec(str));//null console.log(reg.lastIndex);//0
var reg = /\w+\s/g; var str = "fee fi fo fum"; var xArray; while (xArray = reg.exec(str)) console.log(xArray); // ["fee ", index: 0, input: "fee fi fo fum"] // ["fi ", index: 4, input: "fee fi fo fum"] // ["fo ", index: 7, input: "fee fi fo fum"]
若是在reg匹配过以后要换一个字符串从新进行匹配,那么须要手动把reg.lastIndex
设置为0,不然回像下面这样明明存在却匹配不出来。
var reg = new RegExp(/hui/ig); var str = 'hui hui hui Like Summer'; console.log("lastIndex:" + reg.lastIndex); //0 console.log(reg.exec(str)); console.log("lastIndex:" + reg.lastIndex); //3 console.log(reg.exec('hui Like Summer'));
同时exec相比于match返回的信息要详细的多。
var reg = new RegExp(/hui/ig); var str = ' HuiDT hui hui hui Like Summer'; console.log(reg.exec(' HuiDT hui hui hui Like Summer')); console.log(reg.exec(str)); console.log(/hui/ig.exec(' HuiDT hui hui hui Like Summer')); console.log(/hui/ig.exec(str));
看字符串中是否存在正则表达式(经过模式来搜索字符串),返回 true 或 false。
var reg = /hui/; var str = ' huiDT Like Summer'; console.log(reg.test('huiDT Like Summer')); console.log(reg.test(str)); console.log(/hui/.test('huiDT Like Summer')); console.log(/hui/.test(str));
RegExp的每一个实例都具备如下属性,经过这些属性能够获得一些信息。
RegExp构造函数包含一些属性,适用于做用域中的全部正则表达式,这些属性分别有一个长属性和短属性名。
长属性名 | 短属性名 | 说明 |
---|---|---|
input |
$_ |
最近一次要匹配的字符串 |
lastMatch |
$& |
最近一次的匹配项 |
lastParen |
$+ |
最近一次匹配的捕获组 |
leftContext |
$` | input字符串中lastMatch以前的文本 |
multiline |
$* |
布尔值,表示是否全部表达式都是用多行模式 |
rightContext |
$' |
Input字符串中lastMatch以后的文本 |
var reg = /hui/i; var str = 'DT hui Like Summer'; console.log(str.search(reg)); //3 console.log(str.search("hui")); //3 console.log(str.search(/hui/i)); //3 console.log('DT hui Like Summer'.search(reg)); //3 console.log('DT hui Like Summer'.search("hui")); //3 console.log('DT hui Like Summer'.search(/hui/i)); //3
var reg = /hui/i; var str = 'DT hui Like Summer'; var str1 = '会'; console.log(str.replace('DT', '会')); console.log(str.replace(/hui/, '会')); console.log(str.replace(/DT/, str1)); console.log(str.replace(reg, str1)); console.log('DT DT hui Like Summer'.replace(/DT/g, '会'));
var reg = new RegExp("hui", 'ig'); var str = "Huihui Like Summer"; console.log(str.match(reg));
正则表达式由普通字符和特殊字符(元字符)组成,其中普通字符包括非打印字符
表示范围,用来查找指定范围内的字符
var reg = /[abc]/ig; var str = "A a b d hui"; console.log(str.match(reg)); //["A", "a", "b"]
var reg = /[^abc]/ig; var str = "A a b d hui"; console.log(str.match(reg)); // [" ", " ", " ", "d", " ", "h", "u", "i"]
var str = "abchui"; console.log(str.match(/[|a|b|c]/ig)); //["a", "b", "c"] console.log(str.match(/[^|a|b|c]/ig)); //["h", "u", "i"] console.log(str.match(/(^a|b|c)/ig)); //["a", "b", "c"] console.log(str.match(/(a|hui)/ig)); //["a", "hui"]
元字符指拥有特殊含义的字符
在试图匹配它们时要求转义。
特殊字符 | 描述 |
---|---|
. |
查找单个字符,除了换行和行结束符。 |
\w |
查找单词字符(除符号、空格) |
\W |
查找非单词字符。 |
\d |
查找数字。 |
\D |
查找非数字字符。 |
\s |
查找空白字符。 |
\S |
查找非空白字符。 |
\b |
匹配单词边界。 |
\B |
匹配非单词边界。 |
\0 |
查找 NUL 字符。 |
\n |
查找换行符。 |
\f |
查找换页符。 |
\r |
查找回车符。 |
\t |
查找制表符。 |
\v |
查找垂直制表符。 |
\xxx |
查找以八进制数 xxx 规定的字符。 |
\xdd |
查找以十六进制数 dd 规定的字符。 |
\uxxxx |
查找以十六进制数 xxxx 规定的 Unicode 字符。 |
【例】
var str = "Like's 520"; var reg1 = /./ig; console.log(str.match(reg1)); // ["L", "i", "k", "e", "'", "s", " ", "5", "2", "0"] var reg2 = /\w/ig; console.log(str.match(reg2)); //["L", "i", "k", "e", "s", "5", "2", "0"] var reg3 = /\W/ig; console.log(str.match(reg3)); //["'", " "] var reg4 = /\d/ig; console.log(str.match(reg4)); //["5", "2", "0"] var reg5 = /\D/ig; console.log(str.match(reg5)); //["L", "i", "k", "e", "'", "s", " "] var reg6 = /\s/ig; console.log(str.match(reg6)); //[" "] var reg7 = /\S/ig; console.log(str.match(reg7)); //["L", "i", "k", "e", "'", "s", "5", "2", "0"] var reg8 = /\b/ig; //单词边界,找单词旁边的空格 console.log(str.match(reg8)); //(6) ["", "", "", "", "", ""] var reg9 = /\B/ig; //非单词边界,找连续单词之间的间隔有几个 console.log(str.match(reg9)); //(5) ["", "", "", "", ""] console.log("1234567".match(reg9)); //(6) ["", "", "", "", "", ""] str = "Like's hui A ቐ W \0 \n \f \r \t \v 0b10 070 0xaa "; var reg10 = /\0/ig; console.log(str.match(reg10)); var reg11 = /\n/ig; console.log(str.match(reg11)); var reg12 = /\f/ig; console.log(str.match(reg12)); var reg13 = /\r/ig; console.log(str.match(reg13)); var reg14 = /\t/ig; console.log(str.match(reg14)); var reg15 = /\v/ig; console.log(str.match(reg15)); //[""] var reg16 = /\150/g; // 找八进制数 console.log(str.match(reg16)); var reg17 = /\151/g; //找八进制数 console.log(str.match(reg17)); console.log(str.match(/\x57/g)); //找十六进制数 var reg18 = /\u0041/g; //查找以十六进制数 xxxx 规定的 Unicode 字符 console.log(str.match(reg18)); console.log(str.match(/\u1250/));
( [ { \ ^ $ | ) ? * + . ] }
用法参考:https://developer.mozilla.org...
元字符 | 描述 | |||
---|---|---|---|---|
$ |
匹配输入字符串的结尾位置。若是设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n ' 或 '\r '。要匹配 $ 字符自己,请使用 \$ 。 |
|||
( ) |
标记一个子表达式的开始和结束位置。子表达式能够获取供之后使用。要匹配这些字符,请使用 \( 和 \) 。 |
|||
* |
匹配前面的子表达式零次或屡次。要匹配 * 字符,请使用 \* 。 |
|||
+ |
匹配前面的子表达式一次或屡次。要匹配 + 字符,请使用 \+ 。 |
|||
. |
匹配除换行符 \n 以外的任何单字符。要匹配 .,请使用 \ 。 |
|||
[ |
标记一个中括号表达式的开始。要匹配 [ ,请使用 \[ 。 |
|||
? |
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 |
。 | ||
\ |
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n ' 匹配换行符。序列 '\\ ' 匹配 "\ ",而 '\( ' 则匹配 "( "。 |
|||
^ |
匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符自己,请使用 \^ 。 |
|||
{ |
标记限定符表达式的开始。要匹配 { ,请使用 \{ 。 |
|||
`\ | ` | 指明两项之间的一个选择。要匹配 `\ | ,请使用 `\ |
字符 | 描述 |
---|---|
\cx |
匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。不然,将 c 视为一个原义的 'c' 字符。 |
\f |
匹配一个换页符。等价于 \x0c 和 \cL 。 |
\n |
匹配一个换行符。等价于 \x0a 和 \cJ 。 |
\r |
匹配一个回车符。等价于 \x0d 和 \cM 。 |
\s |
匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] 。 |
\S |
匹配任何非空白字符。等价于 [^ \f\n\r\t\v] 。 |
\t |
匹配一个制表符。等价于 \x09 和 \cI 。 |
\v |
匹配一个垂直制表符。等价于 \x0b 和 \cK 。 |
var str = "hui hello fuck! Orange Trump"; str1 = str.replace(/(\w+)\s+(\w+)/g, "$2,$1"); console.log(str1); //hello,hui fuck! Trump,Orange
ECMAScript缺乏某些语言所支持的该机正则表达式特性(特别是perl)。