Skip to content

JavaScript 正则表达式 #24

Description

@Calerme

正则表达式图形化

REGEXPER

创建方法

字面量:

var reg = /\bis\b/g;

构造函数:

var reg = new RegExp('\\bis\\b', 'g');

修饰符

  • g
  • y
  • i
  • m 多行搜索

多行匹配:

`@123
@456
@789`.replace(/^@./g, 'x'); // 只有 @1 可以被匹配到

`@123
@456
@789`.replace(/^@./gm, 'x'); // @1 @4 @7 都可以被匹配到

基本字符类型

正则表达式由两种基本的字符类型组成:

  • 原义文本字符
  • 元字符 . * + ? $ ^ | \ () {} []

字符类

  • [abc]
  • [^abc]
var reg = /[abc]/; // 匹配 abc 中任意一个字符
// 取反
var reg = /[^abc]/; // 匹配非 abc 中的字符

范围类

  • [a-z] 闭合区间,包括 a 和 z 本身
  • [a-zA-Z]

预定义类

符号 作用
. 除回车换行外的所有字符
\d 数字字符 === [0-9]
\D 非数字字符 === [^0-9]
\s 匹配一个空白字符
\S 匹配一个非空白字符
\w 单词字符(字母、数字、下划线) === [a-zA-Z_0-9]
\W 非单词字符 === [^a-zA-Z_0-9]
\b 单词边界 便:\bis\b
\B 非单词边界
^ 以……开始
$ 以……结束

量词

符号 含义
? 0 次或 1 次(最多 1 次)
  • | 1 次 或多次(最少 1 次)
  • | 0 次或任意次
    {n} | n 次
    {n,m} | n~m 次
    {n,} | 至少出现 n 次

贪婪模式

尽可能多地匹配。默认为贪婪模式。

'12345678'.replace(/\d{3,6}/, 'x'); // -> 'x78'

非贪婪模式

尽可能少得匹配。使用在量词后加 ? 号表示。

'12345678'.replace(/\d{3,6}?/, 'x'); // -> 'x45678'

分组

作用:

  • 限定量词作用的范围
  • 配合 “或” 符号
  • 分组的反向引用(分组捕获)
/javascript{3}/ // t 重复 3 次
/(javascript){3}/ // javascript 重复 3 次

分组捕获:

示例,年月日 -> 月日年

'2017-01-01'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2-$3-$1');

忽略分组:

在分组前添加 ?:

'2017-01-01'.replace(/(?:\d{4})-(?:\d{2})-(\d{2})/, '$1-$2-$3'); // $1 匹配第三个分组,$2 $3 没有匹配值

前瞻后顾

前瞻

  • 正则表达式从文本头部向尾部开始解析,文本尾部方向称为前

  • 前瞻就是在匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反

  • 符合和不符合特定断言称为肯定/正向匹配和否定/负向匹配

  • 正向前瞻 exp(?=assert)

  • 负向前瞻 exp(?!assert)

示例:

// 断言,匹配项后边必须有一个数字
'a2*3'.replace(/\w(?=\d)/g, 'x'); // -> "x2*3"
'a2*34vv'.replace(/\w(?=\d)/g, 'x'); // -> "x2*x4vv'

// 断言,匹配项后边必须不是一个数字
'a2*34vv'.replace(/\w(?!\d)/g, 'x'); // -> "ax*3xxx"

后顾

  • ES6 开始支持后顾
  • (?<=assert)exp
  • (?<!assert)exp

正则对象实例上的属性

  • global
  • ignoreCase
  • multiline
  • lastIndex 如果正则拥有 g/y 修饰符,该值将被记为下一次搜索的位置,直至找不到时重置为 0。非全局模式该值永远是 0。
  • source 正则表达式的文本字符串

正则表达式实例上的方法

  • RegExp.prototype.test()
  • RegExp.prototype.exec()

RegExp.prototype.test() 返回一个布尔值,表示参数字符串中是否存在匹配正则的字符串。==当正则为全局模式时,每次调用 test 都会从正则的 lastIndex 开始向后查找==:

/abc/.test('abcdefg'); // -> true

**RegExp.prototype.exec()**没有匹配到值返回 null,匹配到返回一个结果数组,该数组的第一个值为匹配到的值,之后紧跟着的为匹配到的分组值:

  • result[0] - 匹配到的结果
  • result[1] - 分组 1
  • result[2] - 分组 2
  • result[3] - 分组 3
  • result[n] - 分组 n

该数组还有两个值,分别为:

  • result.index - 匹配到字符串的开始索引
  • result.input - 返回被匹配的整个字符串

字符串对象实例与正则相关的方法

  • String.prototype.search()
  • String.prototype.match()
  • String.prototype.split()
  • String.prototype.replace()

**String.prototype.search()**返回每一个匹配到 index,查不到返回 -1,该方法不支持全局匹配,忽略 g 修饰符。

String.prototype.match(),返回的值基本与 RegExp.prototype.exec() 返回的值相同。不同的是如果正则是全局模式,它返回的数组包括所有的匹配项,而 exec() 需要循环调用自身查找所有匹配项。

String.prototype.split(),以匹配到的字符分割字符串。

String.prototype.replace(reg, function (匹配到的字符串, 分组1, 分组2, ..., index, 原字符串) { return newStr; })

'abcdefg'.replace(reg, function (匹配到的字符串, 分组1, 分组2, ..., index, 原字符串) { 
    return newStr; 
});

其实以上方法的参数即使传入的是字符串,JavaScript 也会将它们转换为正则表达式。

一些示例

// 匹配以 jpg 结尾的 URL 地址
/http:\/\/.+\.jpg/

// 匹配 YYYY/MM/DD 或 YYYY-MM-DD 格式
/\d{4}[/-]\d{2}[/-]\d{2}/

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions