正则表达式

匹配模式

  • i —— 忽略大小写
  • g —— 全局匹配
  • m —— 多行匹配(要匹配的字符串中间有换行,通常和 g 一起使用)
var str1 = 'ababab';
var str2 = 'ab\nabc';

var regexp1 = /ab/g;
var regexp2 = /ab/m;
var regexp3 = /^ab/g;
var regexp4 = /^ab/m;
var regexp5 = /^ab/mg;

var res1 = str1.match(regexp1);
var res2 = str1.match(regexp2);

var res3 = str2.match(regexp1);
var res4 = str2.match(regexp2);
var res5 = str2.match(regexp3);
var res6 = str2.match(regexp4);
var res7 = str2.match(regexp5);

console.log(res1);//[ 'ab', 'ab', 'ab' ]
console.log(res2);//[ 'ab', index: 0, input: 'ababab', groups: undefined ]

console.log(res3);//[ 'ab', 'ab' ]
console.log(res4);//[ 'ab', index: 0, input: 'ab\nabc', groups: undefined ]
console.log(res5);//[ 'ab' ]
console.log(res6);//[ 'ab', index: 0, input: 'ab\nabc', groups: undefined ]
console.log(res7);//[ 'ab', 'ab' ]

表达式

ps:

1.正则里面规则是从左到右的(按顺序)

2.字符串被匹配完以后就不会再被匹配了,不会!!!!!!!!!

  • [] —— 表达式, 一个 " [] "(表达式) 代表一位, 里面的内容表示的是这一位可以取到的范围
  • [^] —— !表达式,里面的内容表示的是这一位不可以取得值
  • [a-z]
  • [A-Z]
  • [A-z] ——  A(ASCI码:65)-Z + a(ASC码:97)-z
  • [0-9]
  • [\u4e00-\u9fa5] ——  中文
  • () —— 子表达式(分组),代表一个表达式区间

() 和 [] 的区别?

var reg1 = /[abc|def|ghi]/g;
var reg2 = /(abc|def|ghi)/g;

var str = 'mnvcva';

reg1.test(str); //true
reg2.test(str); //false

元字符 

其实也是表达式,是表达式的翻译版本

  • \w —— === [0-9A-z_] 
  • \W —— === [^\w]
  • \d —— === [0-9]
  • \D —— ===[^\d]
  • \s —— 空白字符,包括 \n , \r , \f , \t , \v
  • \S —— [^\s]
  • \b —— 单词边界
  • \B —— 非单词边界
  •  . —— [^\r\n] 除了\r ,\n的任意字符

单词边界?

eg1.
var str = 'abc def ghi'; //有6个单词边界

eg2.
var reg = /\bcde/g;
var str = 'abc cde fgh';
str.match(reg); // ["cde"]

var reg2 = /\bcde\b/g;
str.match(reg2); // ["cde"]

var str2 = "abc cdefgh";
str2.match(reg2); // null

量词

注意:能匹配多不匹配少(正则是贪婪匹配原则),会尽可能多的匹配

  • n+ —— {1, } 
  • n* —— {0, } 
var reg = /\w*/g;
var str = 'abc';

str.match(reg); // ["abc", ""] 
// 为什么还有个""?
// 因为 正则的匹配是全局的,当匹配完abc,光标所在的位置是c,c后面还有一个逻辑位,被匹配为了""

var reg = /\d*/g;
var str = 'abc';
str.match(reg); //["","","",""] 匹配的是4个逻辑位(好像不叫逻辑位~,叫什么忘记了)
  • n? —— {0, 1}
  • n{X} —— {x}
  • n{x, y} —— {x, y}
  • n{x,} —— {x, }
  • ?=n —— 正向预查(也可叫正向断言)(后面有详细使用方法)
  • ?!n —— 非正向预查(非正向断言)

反向引用

反向引用:var reg = /(\w)/  ——  其中"()" (括号)会记录里面所匹配的内容, 可以利用 “\1” 来引用出来!“\1” 表示的是引用第一个子表达式(分组)(即第一个括号)里面的内容,以此类推,“\2” 表示的是引用第二个子表达式(分组)里面的内容

举个栗子

var reg = /(\w)\1\1\1/g;
var str = 'aaaabbbb';

str.match(reg); // ["aaaa", "bbbb"]

正则表达式实例的方法和属性

注意:如果要返回的是匹配得到的结果,它都是根据正则的规则,匹配到的内容!而不包含其他!!!!

方法:

  • regexp.test(string) 字符串是否符合正则的规则  —— true / false
  • regexp.exec(string) ——

(1)返回一个类数组 [{"匹配的内容", index: xx, input: '匹配的字符串',groups:xx}]

(2)当正则里面有子表达式时:返回一个类数组[{"匹配的内容",“第一个子表达式匹配的内容”, "第二个子表达式匹配的内容", .... index: xx, input: .....同上}]

var reg = /ab/g;
var str = 'ababab';

console.log(reg.exec(str))
//["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex)
//2

console.log(reg.exec(str))
//["ab", index: 2, input: "ababab", groups: undefined]
console.log(reg.lastIndex)
//4

console.log(reg.exec(str))
//["ab", index: 4, input: "ababab", groups: undefined]
console.log(reg.lastIndex)
//6

console.log(reg.exec(str))
//null
console.log(reg.lastIndex)
//0

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

var reg = /ab/;
var str = 'ababab';

console.log(reg.exec(str))
// ["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex)
//0

console.log(reg.exec(str))
// ["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex)
//0


_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

所以,如果正则的匹配模式不是 global 的时候,游标的位置每次都是0

字符串中与正则相关的方法:

  • string.match(regexp)  —— 返回匹配了正则的字符串数组 (这个是字符串的方法)

(1)当不是全局匹配,返回的是一个类数组:["匹配到的内容", index: xx, input: '原始字符串', groups: ...]

(2)如果式全局匹配,返回的是一个数组:["匹配的第一个值", "匹配的第二个值", ...],数组里面的每一项都是根据正则所匹配到的内容

  • string.search(regexp) —— 返回匹配的位置(与lastIndex没有关系),匹配不到返回 -1 。
var reg = /abc/g;
var reg2 = /abc/;

var str = 'fk abc def abc';

console.log(str.search(reg));//3
console.log(str.search(reg2));//3

// 无论是不是全局匹配,返回的结果都是一样的,所以它与lastIndex的值无关系
  • string.split(regexp)  —— 按照正则拆分字符串
  • string.replace(regexp ,func / string})  —— 替换内容(第一个参数也可以是字符串),第二个参数可以是一个匹配正则后的回调函数(每次匹配都会执行),也可以是一个字符串表示匹配的内容替换成什么。

注意:replace的第二个参数如果是回调函数,是匹配一次执行一次!!!!

举个栗子:如果第二个参数是一个字符串

AABB式 处理后 变成 BBAA 式
var reg = /(\w)\1(\w)\2/g;
var str = 'aabb';

var retStr = str.replace(reg, "$2$2$1$1"); 
//$1:第一个子表达式里面的内容 
//$2:第二个子表达式里面的内容
//结果:retStr --> bbaa

举个栗子:如果第二个参数是匹配内容后的回调函数

AABB 式 替换后 BBAA式

var str = 'aabb';
var reg = /(\w)\1(\w)\2/g;

var retStr = str.replace(reg, function($, $1, $2) {
    console.log(arguments);
    // 第一个参数是匹配到的内容,第二个参数是第一个子表达式匹配到的内容,以此类推,然后是匹配的索引位置...
    // ["aabb", "a", "b", 0, "aabbccdd", callee:....] //第一次执行时的输出
    return $2+$2+$1+$1;
});

实例:the-first-name 处理后 变成 小驼峰式的写法

var reg = /-(\w)/g;
var str = 'the-first-name';

//思路:将 -f、-n 分别替换成 F 、N

str.replace(reg, function($, $1) {
    return $1.toUpperCase();
});

属性:

  • regexp.ignoreCase
  • regexp.global
  • regexp.multiline
  • regexp.source  —— 正则表达式内部的内容
  • regexp.lastIndex —— 通常与 exec 方法相搭配使用
var reg = /ab/g;
var str = 'ababab';

console.log(reg.exec(str));
///["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex);
//2

console.log(reg.exec(str));
///["ab", index: 2, input: "ababab", groups: undefined]
console.log(reg.lastIndex);
//4

reg.lastIndex = 0; // 当将游标的位置重置为0后
console.log(reg.lastIndex); // 0

console.log(reg.exec(str)); //游标重置为0了,所以又重头开始匹配
///["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex);
//2

正向预查(正向断言)

正向预查:?=n  

如:n1(?=n2):n2 不参与选择,只负责修饰(限定) n1 ,匹配到的内容为 n1 后面紧跟着是 n2 的 n1

// 查询字符串 'abaaaa' 中 后面是b的a

var str = 'abaaaa';
var reg = /a(?=b)/g;

str.match(reg); // ["a"]

非正向预查 ?!n

如:n1(?!n2):n2 不参与选择,只负责修饰 n1,匹配到的内容为 n1 后面紧跟着的不是 n2 的 n1

// 查询字符串 'baaaa' 中 后面不是b的a

var str = 'abaaaa';
var reg = /a(?!b)/g;

str.match(reg);
//["a", "a", "a", "a"]

非贪婪匹配

正则默认是 贪婪匹配 , 就是尽可能多的匹配正则里面的规则

非贪婪匹配:与贪婪匹配相反,就是尽可能少的匹配,能匹配一个,就不会匹配多个

非贪婪匹配只要在量词后面加个 “?” 就可以了~

举个栗子:

//举个栗子:
var str = 'aabca';

//贪婪匹配:
var reg1 = /a+/g;
str.match(reg1); 
//["aa", "a"]

//非贪婪匹配:
var reg2 = /a+?/g;
str.match(reg2);
//["a", "a", "a"]

习题:

1. 检验一个字符串首/尾是否包含数字

var reg = /^\d|\d$/;

2. 检验一个字符串首尾是否都含有数字

var reg = /^\d[\s\S]*\d$/;

3. 匹配字符串中连续的4个相同的字符(如 aaaa、ffff等)

var reg = /(\w)\1\1\1/g;
var str = 'aaaaddbfebbbbi';

str.match(reg); //["aaaa", "bbbb"]

4. 匹配字符串中AABB格式的字符(如 aabb 、ccdd等)

var reg = /(\w)\1(\w)(?!\1)\2/g; //(?!\1) --> 第二个子表达式匹配的内容不与第一个子表达式相同
var str = 'aabbeeiccddffff';

str.match(reg); //["aabb", "ccdd"]

5. 字符串AABB式替换成BBAA式

var reg = /(\w)\1(\w)(?!\1)\2/g;
var str = 'aabbeeiccddffff';

str.replace(reg, "$2$2$1$1"); //bbaaeeiddccffff

6. 将the-first-name替换成theFirstName

var reg = /-(\w)/g;
var str = 'the-first-name';

str.replace(reg, function($, $1) { return $1.toUpperCase()}); //theFirstName

7. 将字符串 "aaaaaabbbbbbbccddd" 替换成 "abcd" 

var str = "aaaaaabbbbbbbccddd";
var reg = /(\w)\1*/g;

str.replace(reg, "$1"); //abcd

8. 将字符串 100000000 转换为 从后面往前面查每隔三位加一个“.” , 即 100.000.000

var reg = /(?=((\d{3})+$))/;
// (\d{3})+$ ————> 以3的倍数个结尾的数字
// (?=((\d{3})+$))————> 正向预查:匹配一个位置,这个位置后面有3或3的倍数个数字
var str = "100000000";
var str2 = "10000000";

str2.replace(reg, "."); //结果:"10.000.000
str.replace(reg, "."); //结果:".100.000.000

//上面的正则没有考虑到字符串的长度如果是3的倍数的话,会在开头的位置也加一个“.”
//(\B) 非单词边界
//?=(\B)((\d{3})+$) 匹配一个位置:这个位置是非单词边界并且后面有3或者3的倍数个数字
var reg = /(?=(\B)((\d{3})+$))/;
var str = "100000000";

str.replace(reg, "."); //100.000.000

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值