代码中使用正则表达式
itagn opened this issue · 0 comments
1 基础
1.1 学习的意义
正则表达式脱离语言,和数据结构与算法一样,作为程序员的软技能。目前存在的问题:不受重视
优点:
- 显著的提升代码质量
- 灵活多变
- 强大的数据校验支持
1.2 构建
构建正则表达式的方式很多,有以下的构造方法。
var regex1 = /itagn/g;
var regex2 = new RegExp('itagn', 'g');
var regex3 = new RegExp(/itagn/, 'g');
var regex4 = new RegExp(/itagn/g);
1.3 修饰符
常用的修饰符:
g: 全局匹配模式。作用于所有字符串,发现第一个匹配项后不会立即停止
i: 不区分大小写模式。忽略大小写进行匹配
m: 多行匹配模式。支持换行文本匹配
新增的修饰符:
u: Unicode模式。用来处理Unicode大于 \uFFFF的单个字符(超过\uFFFF会被程序员解析为两个字符)
y: 粘连模式。和g一样作为全局匹配,区别是g的下一次匹配不要求位置,但是y下一次匹配要求紧跟这这次匹配项之后
s: dotAll模式。正则表达式中点(.)作为匹配(除换行符\n,回车符\r,行分隔符,段分隔符)任意单个字符,支持点(.)真正匹配所有单个字符
2 匹配规则
2.1 关键词匹配
常用的匹配方式,通常是通过匹配关键词来实现定位
示例1:正则设定手机号格式
var regex = /^(086-)?1[345789]\d{9}$/;
regex.test('15512341234'); // true
示例2:正则将时间格式转换:年/月/日(yyyy/mm/dd)
var date = new Date();
var time = date.toISOString();
var regex = /^(\d{4})-(\d{2})-(\d{2})(.+)$/;
time.replace(regex, '$1/$2/$3'); // "2019/08/23"
2.2 位置匹配
常用的位置匹配就是^(匹配字符串开头)和$(匹配字符串结尾)。
另外还有\b(匹配一个单词边界),\B(匹配非单词边界)
示例1:把字符串中所有单词的首字母大写
var regex = /\b[a-z]/g;
var str = 'i am itagn who is a web developers';
str.replace(regex, word => word.toUpperCase()); // "I Am Itagn Who Is A Web Developers"
示例2:把字符串中所有每超过3个字符的单词就增加一个短横(-)
var regex = /[a-zA-Z]{3}\B/g;
var str = 'i am itagn who is a web developers';
str.replace(regex, word => word + '-'); // "i am ita-gn who is a web dev-elo-per-s"
3 高级用法
3.1 贪婪匹配
贪婪匹配:趋向于最大长度匹配。(默认)
非贪婪匹配:匹配到结果就好。
示例1:贪婪匹配
获取数字
'123456789'.match(/\d+/)[0]; // "123456789"
示例2:非贪婪匹配
获取数字
'123456789'.match(/\d+?/)[0]; // "1"
3.2 懒惰匹配
上文中的非贪婪匹配就用到了惰性匹配,其特点就是在其他重复量词
后面加上限定符(?)
惰性匹配的特点:
- 重复量词后面添加限定符(?)
- 惰性匹配会尽可能少的匹配字符,同时必须满足整个匹配模式。
示例1:非惰性匹配
和惰性匹配
'123412341234'.match(/1(\d+)4/)[0]; // "123412341234"
'123412341234'.match(/1(\d+?)4/)[0]; // "1234"
3.3 先行断言/先行否定断言
先行断言:x只有在y前面才匹配,必须写成/x(?=y)/的形式。
先行否定断言:x只有不在y前面才匹配,必须写成/x(?!y)/的形式。
匹配的结果是x,如通过match方法匹配项会返回x。
示例1:先行断言
和先行否定断言
的用法
/itagn(?=2019)/.test('itagn2019'); // true
/itagn(?=2019)/.test('itagn-2019'); // false
/itagn(?!2019)/.test('itagn2019'); // false
/itagn(?!2019)/.test('itagn-2019'); // true
我们可以发现,这里同时包含了关键词匹配
和位置匹配
,属于正则的高级匹配。
接下来我们可以看看怎么处理业务中的问题。
示例2:通过正则把数字 1234567890
转换成美元 $1,234,567,890
var str = '1234567890';
var regex = /(?!^)(?=(\d{3})+$)/g;
str.replace(regex, ',').replace(/^/, '$'); // "$1,234,567,890"
3.4 后行断言/后行否定断言
后行断言和先行断言正好相反。
后行断言:x只有在y后面才匹配,必须写成/(?<=y)x/的形式。
后行否定断言:x只有不再y后面才匹配,必须写成/(?<!y)x/的形式。
匹配的结果是x,如通过match方法匹配项会返回x。
示例1:后行断言
和后行否定断言
的用法
/(?<=2019)itagn/.test('2019itagn'); // true
/(?<=2019)itagn/.test('2019-itagn'); // false
/(?<!2019)itagn/.test('2019itagn'); // false
/(?<!2019)itagn/.test('2019-itagn'); // true
示例2:通过正则把美元 $123,456,789,000
变成美元 $1234,5678,9000
试着通过先行断言
+先行否定断言
来处理
var str = '$123,456,789,000';
var regex = /(?!^)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$,1234,5678,9000"
由于第一个字符是$而不是数字,在这里先行否定断言
判断字符串初始无效,所以在$和数字中间出现了逗号分隔符。
同时也不能把(?!^)改成(?!$),因为匹配到1234,56789,000的时候前面的字符也不是$而是1,所以仍然会在开头添加一个逗号(,)。
var str = '$123,456,789,000';
var regex = /(?!\$)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$,1234,5678,9000"
我们发现,我们只需要排除一种情况,就是$后面跟着逗号的情况。
这个时候满足后行断言匹配项(x)在美元符号$后面。
试着通过后行否定断言
代替先行否定断言
。
var str = '$123,456,789,000';
var regex = /(?<!\$)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$1234,5678,9000"