Javascript 正则表达式

正则表达式

REGEXP对象

javascript通过内置对象Regexp支持正则表达式。

两种方法来创建Regexp对象。

1、字面量

var reg = /\b\d{4}\b/g;
// g 表示进行全局替换

2、构造函数

var reg = new RegExp('\\b\\d{4}\\b','g');

// 这里因为是字符串,需要对特殊字符进行转义
// 利用正则进行文本替换
var reg = new RegExp('\\bis\\b','g');
"what is this?".replace(reg, 'IS');

// "what IS this?"

修饰符

  • g : global 全文搜索,如果不添加的话,搜索到第一个就匹配停止
  • i : ignore case 忽略大小写,默认大小写敏感
  • m : multiple lines 多行搜索
'He is a boy. Is he?'.replace(/\bis\b/g, '0');
// 'He 0 a boy. Is he?'

'He is a boy. Is he?'.replace(/\bis\b/gi, '0');
// 'He 0 a boy. 0 he?'

元字符

正则表达式中有着两种基本字符,原义文本字符元字符

原义文本字符: a b f r ...

元字符: 指有特殊含义的非字母字符 b t ...

正则表达式中的特殊字符: * + ? $ ^ . | [] {} ()

字符类

  • 我们可以使用 元字符 [] 来构造一个简单的类
  • 所谓类,就是符合某一个特征的对象,是泛指。
  • [abc]a b c 归为一类,表达式可以匹配这类字符
  • 使用 ^可以取反,创建反向类,表示匹配不符合的字符
'a1b3c342bb'.replace(/[abc]/g, 'X');
// "X1X3X342XX"

'a1b3c342bb'.replace(/[^abc]/g, 'X');
// "aXbXcXXXbb"

范围类

  • 使用 [a-z]来链接两个字符表示从 az的任意字符;
  • [a-zA-Z0-9]

预定义类和边界

预定义类

* .  [^\r\n]  除了回车换行之外的任意字符

* \d [0-9]    数字

* \D [^0-9]   非数字

* \s [\t\n\f\r\x0B]  空白符

* \S [^\t\n\f\r\x0B] 非空白符

* \w [0-9a-zA-Z_]  字母数字下划线

* \W [^0-9a-zA-Z_] 非字母数字下划线

边界

^ 开头

$ 结尾

b 单词边界

B 非单词边界

'@abc@ab@'.replace(/@./g, 'Q');
// "QbcQb@"

'@abc@ab@'.replace(/^@./g, 'Q');
// "Qbc@ab@"

'@abc@ab@'.replace(/.@$/g, 'Q');
// "@abc@aQ"
// 验证 m 表示多行搜索
var mulSrt="@123\n@456\n%890";

mulSrt.replace(/@\d/gm, 'X');

"X23
X56
%890"

量词

* ?  出现0次或者一次   0/1

* +  至少出现1次      >= 1

* *  出现零次或者一次  >= 0 

* {n} 出现n次

* {n, m} 出现 n 到 m 次

* {n, }  至少出现n 次

贪婪模式和非贪婪模式

/\d{3,6}/

匹配 12345678 得到 123456

// 这就是贪婪模式

非贪婪模式

让正则表达式尽可能的少匹配,也就是说一旦匹配成功就不在继续尝试。[做法很简单,就是在量词后添加一个?即可]

/\d{3,5}?/g

分组

  • ()分组
'a1b2c3d4'.replace(/[a-z]\d{3}/g, 'X');
// a1b2c3d4

'a1b2c3d4'.replace(/([a-z]\d){3}/g, 'X');
// Xd4
  • 或 |
'meiaals'.replace(/[a-z]+(aa|bb)[a-z]+/g, '0');
// 0

'meibbls'.replace(/[a-z]+(aa|bb)[a-z]+/g, '0');
// 0
  • 分组取值
'2016-04-23'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$3-$2-$1');

// "23-04-2016"

前瞻

“正则表达式是从文本头部向尾部解析”。这就像在走路,没走过的路在你的前面,需要你往前看(前瞻);走过的路需要你回头看(后顾)

[js不支持后顾]

  • 正向前瞻exp(?=assert)
  • 负向前瞻exp(?!assert)
'a2*3'.replace(/\w(?=\d)/g, 'X');
// "X2*3"

对象属性

  • global:是否全文搜索,默认false
  • ignore case:是否大小写敏感,默认是false
  • multiline:多行搜索,默认值是false
  • lastIndex:当前表达式匹配内容的最后一个字符的下一个位置
  • source:正则表达式的文本字符串
let regex = /(\d{4}\1)-(\d{2})-(\d{2})/g;

regex.source
// "(\d{4}\1)-(\d{2})-(\d{2})"

RegExp对象本身的方法

RegExp.prototype.test(str)

用户测试某一个字符串是否存在匹配正则表达式模式的字符串,如果存在就返回true 、 否则 返回 false。

var reg2=/\w/g;

进行reg2.test('ab')时,第三次会变成false

原因:
while(reg2.test('ab')){
   console.log(reg2.lastIndex);
}

RegExp.prototype.exec(str)

如果没有匹配返回null,如果匹配成功,返回一个数组。(index: 匹配文本的第一个字符的位置,input: 存放被检索的字符串的string);

var reg = /\d(\w)(\w)\d/g;

var str = '$1ab343sdd5ef6';
var ret;
while(ret = reg.exec(str)) {
    console.log(ret[0] +'-'+ret[1] +'-'+ret[2]); 
    console.log(ret.index); 
}
// ["1ab3", "a", "b", index: 1, input: "$1ab343sdd5ef6", groups: undefined]

// ["5ef6", "e", "f", index: 10, input: "$1ab343sdd5ef6", groups: undefined]

// 第一个为匹配的字符串, 第二项之后都是分组内容

String对象本身的方法

String.prototype.search(reg)

用于检索字符串中指定的子字符串、或者检索于正则匹配的子字符串。返回一个index, 如果没有找到返回-1. [忽略g,并且每次都是从开头匹配];

'wwasdasf7'.search(/\d/);
// 8

String.prototype.match(reg)

match方法将检索字符串,以找到一个或者多个与regexp匹配的文本。
(是否有g影响很大)

  • 如果找到了就返回一个数组,如果没有找到,返回null
var reg = /\d(\w)(\w)\d/g;

var str = '$1ab343sdd5ef6';
var ret = str.match(reg);
console.log(ret);
// ["1ab3", "5ef6"]

String.prototype.split(str/reg)

'a,d,f,g,h'.split(',');
// ["a", "d", "f", "g", "h"]

'a1b1c2d3f5'.split(/\d/g);
// ["a", "b", "c", "d", "f", ""]

String.prototype.replace(str, replacestr)

'asd231'.replace('2', 'S');

String.prototype.replace(reg, replacestr)

'asd231'.replace(/\d+/g, 'S');

String.prototype.replace(reg, function)

// a1b2c3d4 => z2b3c4d5

'a1b2c3d4'.replace(/\d/g, function(match, index, origin){
    console.log(index);
    return parseInt(match) + 1;
})
// "a2b3c4d5"

相关推荐