[关闭]
@Dale-Lin 2022-07-29T17:28:10.000000Z 字数 4821 阅读 709

JS RegExp

JavaScript


Regular Expression(正则表达式):使用单个字符串来描述,匹配一系列符合某语法规则的字符串。简单来说就是按某种规则去匹配符合条件的字符串。

在线测试工具:REGEXPER


字面量语法:

var reg = / expression / flags;

构造函数:

var rag = new RegExp( 'expression' , 'falgs' );

注意,在这里的表达式中传入的特殊字符要转义(包括转义符 )


元字符

字符 含义
\t 水平制表符
\v 垂直制表符
\n 换行符
\r 回车符
\0 空字符
\f 换页符
\cX 与X对应的控制字符(此表示Ctrl+X)
[\u4e00-\u9fa5\uf900-\ufa2d] 中文字符

字符 等价类 含义
. [^\r\n] 除了回车符和换行符之外的所有字符
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\s [\t\n\x0B\f\r] 空白符(\x0B 是垂直制表符)
\S [^\t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 单词字符(字母、数字、下划线)
\W [^a-zA-Z_0-9] 非单词字符

\w 也包括 \d


Boundaries

Character Meaning
^ Match beginning of input. If the multiline flag is set to true, also matches immediately after a line break character.
$ Matches end of input. If the multiline flag is set to true, also matches immediately after a line break character.
\b Matches a word boundary. This is the position where a word character is not followed or preceded by another word-character, such as between a letter and a space.
\B Matches a non-word boundary. This is a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. Such as between two letters or between two spaces.

量词

字符 含义
? 出现零次或一次(最多出现一次)
+ 出现一次或多次(至少出现一次)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次

例如:

    \d{2} 表示连续出现两次数字
    \d{0,10} 表示最多连续出现十次数字

量词的贪婪与非贪婪模式

默认情况下,正则表达式匹配时会尽可能多地匹配字符串 (贪婪模式)
量词(包括 * + ? {}) 后面加上 即可让正则表达式匹配尽量少的字符串 (非贪婪模式)

分组:
使用 () 可以达到分组的功能,使量词作用于分组。(否则量词只作用于前一个字符)
规定没有匹配项的分组在exec()结果数组中用undefined表示。


可以使用 | 达到 的效果


忽略分组

不希望捕获某些分组,只需要在分组内加上?: 就可以。
例如:

    (?:Byron).(ok)

这样就忽略了第一个分组,只捕获了 "ok" ,并作为 $1。


前瞻/后顾

在表达式内使用 (?=assert) (?!assert) (?<=assert) (?<!assert)(不会作为匹配结果,只作为判断)

名称 正则
正前瞻(positive lookahead) exp(?=assert)
负前瞻(negative lookahead) exp(?!assert)
正后顾 exp(?<=assert)
负后顾 exp(?<!assert)

例:

    "a2*3".replace(/\w(?=\d)/g,"X");    //"X2*3"
    "a2*35m0".replace(/\w(?=\d)/g,"X");  //"X2*X5X0"
    "a2*35mm".replace(/\w(?!\d)/g,"X");  //"aX*3XXX"

对象属性


正则表达式方法

test():用于测试字符串参数中是否存在匹配正则表达式模式的字符串,存在则返回true,否则返回false。
语法
regexObj.test(str)
执行时注意全局模式下 lastIndex 的更新,在匹配完最后一个后的下一次执行会返回false。

  1. var text = "000-00-0000"
  2. var pattern = /\d{3}-\d{2}-\d{4}/ ;
  3. if(pattern.test(text)){
  4. console.log("The pattern was matched.");
  5. }

在只想检查字符串是否和某模式匹配,而不需要知道其文本内容时(如上例可用在验证用户输入的情况),test() 方法常被用在 if 语句中。


主要方法: exec()
exec() 使用正则表达式模式对字符串执行搜索,全局模式下将更新lastIndex,以反映匹配结果。
若没匹配到文本则返回 null,否则返回一个包含数组的结果。

这个结果可视为一个数组;但当访问该结果的indexinput属性时,表示匹配字符在原字符串中的索引、原字符内容。

语法
regexObj.exec(str)

返回数组:
1. 与正则表达式相匹配的文本
2. 与RegExp对象的第一个子表达式(分组)相匹配的文本(如果有的话)
3. 与RegExp对象的第二个子表达式(分组)相匹配的文本(如果有的话),以此类推
若非全局调用,则忽略 lastIndex 标志,可用于只找第一个匹配结果。
若设置了全局标志,则每次调用会从上一次的结尾后查找新匹配项,但仍然在找到一个(新)匹配项后停止并返回该项。而且 lastIndex 值会增加。

  1. //Match "quick brown" followed by "jumps", ignoring characters in between.
  2. var re = /quick\s(brown).+?=(jumps)/ig;
  3. var result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");

这个程序的返回值如下表:

对象 属性/索引 描述 例子
result [0] 匹配的全部字符串 Quick Brown Fox Jumps
[1],...[n] 括号中的分组捕获 [1] = Brown
[2] = Jumps
index 匹配到的字符位于原始字符串的索引值 4
input 原始字符串 The Quick Brown Fox Jumps Over The Lazy Dog
re lastIndex 下次匹配开始的位置 25
ignoreCase 是否使用'i'忽略大小写 true
global 是否使用'g'全局匹配 true
multiline 是否使用'm'进行多行匹配 false
source 正则匹配的字符串 quick\s(brown).+?(jumps)
  1. var re = /(\w{4}?)\s(\w+)(?=\s) /;
  2. var str = "Some text here waiting for testing.";
  3. if(re.test(str)){
  4. var result = re.exec(str);
  5. console.log(result);
  6. console.log(result[2]);
  7. console.log(result.input);
  8. console.log(result.length);
  9. }

ES9 捕获分组

使用 ?<name> 命名捕获组:

  1. const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<date>[0-9]{2})/,
  2. match = reDate.exec('2018-04-30');

使用 matchResult.groups[name] 使用分组:

  1. match.groups.year; // 2018
  2. match.groups.month; // 04
  3. match.groups.date; // 30

String.replace() 中使用 $<name>

  1. date.replace(reDate, '$<month>-$<date>-$<year>');
  2. // "04-06-2019"

正则表达式的 valueOf() 方法返回正则表达式本身。


可用正则表达式作参数的字符串方法

search()
用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。若有,返回第一个匹配结果的首位的index,否则返回-1。
忽略g标识,不执行全局匹配,并且总是从字符串的开始进行检索。
在传入的参数不是正则表达式时,search方法会尝试把参数转换成正则表达式的形式。



match()
检索字符串,以检索一个或多个与regexp匹配的文本。
regexp是否具有标志g对结果影响很大。

  1. 非全局调用
    match()方法只在字符串中执行一次匹配。
    若没有找到任何匹配的文本,将返回null。
    否则将返回一个数组,其中存放了与它找到的匹配文本有关的信息。数组的第一个元素存放匹配到的文本,而其余元素存放的是与regexp的子表达式(分组)匹配的文本。除了常规的数组元素之外,返回的数组还含有2个对象属性:

    • index 声明匹配文本的起始字符在字符串中的位置。
    • input 声明对 stringObject 的引用。
  2. 全局调用
    match()方法将执行全局搜索,找到字符串中所有匹配的字符串。
    若没找到匹配的字符串,将返回null。
    若找到了一个或多个匹配的字符串,则返回一个数组。存放的是字符串中所有的匹配子串,且没有index属性或input属性。(此处 lastIndex 属性不起作用,为0)



split()
将字符串分割成字符的数组:
语法
str.split(separator, limit)
separator指定拆分发生的字符串:

  1. "a,b,c,d".split(','); //["a","b","c","d"]
  2. //使用第二个参数限制数组大小
  3. var arr = "a,b,c,d";
  4. arr.split(',', 2); //["a","b"]
  5. //当分隔符出现在字符串头或尾时,返回数组的第一项或无限制的最后一项将是空白字符
  6. arr.split(/[^\,]+/); //["", ",", ",", ",", ""]

在一些复杂的分割情况下可以使用正则表达式:

    "a1b2c3d".split(/\d/);  //["a","b","c","d"]

在执行时会尝试将参数转化成正则表达式的形式。
如果在str中不含separator,则返回一个含原字符串的数组。
若separator使用空字符串"",则返回由每个字符组成的数组。



replace()
语法
str.replace(regexp|substr, newSubstr|function)
接收两个参数,第一个是要被替换的字符串或某种正则模式;第二个是替换后的字符串,也可以是一个每次匹配都要调用的函数,即可用function的返回值来作为替换后的动态字符。

若使用函数进行替换,该函数的参数为:

变量名 代表的值
match 匹配的字串
p1,p2... 捕获某个分组
offset 匹配到的子字符串在原字符串中的偏移量
string 被匹配的原字符串
  1. "a1b2c3d4e5".replace(/(\d)(\w)(\d)/g, function (match,p1,p2,p3,offset,string){
  2. console.log(match);
  3. return p1+p2;
  4. }) //'1b2','3d4','a12c34e5'

在执行时会尝试将参数转化成正则表达式的形式。

第一个参数是正则表达式,第二个参数是字符串时,可以使用一些字符序列将正则表达式捕捉到的内容。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注