正则表达式(三)---终
本帖最后由 yuqiaobin 于 2020-2-27 19:36 编辑几点重要但少讲到的内容(掺杂JS,其他语言要灵活变通)
括号
括号优先级就不说了,学过数学的都知道
一.提取出数据
比如提取出年、月、日,可以这么做:
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) );
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]
可以看到,match会返回一个数组,内含各种数据(注意是括号内的哦)
我们可以使用构造函数的全局属性$1至$9来获取:
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
regex.test(string);
console.log(RegExp.$1); // "2017"
console.log(RegExp.$2); // "06"
console.log(RegExp.$3); // "12"
JS测试平台:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
测试结果如图,console.log是在控制台的输出命令
二.引用
以我们之前写过的例子,日期,如2020-02-27or2020/02/27or2020.06.12,按照惯用的想法,你会这么写: /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/
好像看上去没什么问题,如果这样呢2020-02/27,两个符号不一样也匹配到了!
改进方法/\d{4}(-|\/|\.)\d{2}\1\d{2}/
区别就是\1代替了前面了的括号分组,意义:要和前面的一样
那\2,\3,依次指第二个括号分组,第三个括号分组
三.利用非捕获分组(?:p)
别和(?=p)混淆了!
首先介绍下js的match()方法:在字符串中搜索与正则表达式的匹配项,然后将匹配项作为Array对象返回。
var regex = /(?:ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]
这样就能把我们要的内容转存起来
例子:首字母转大写
Another example:利用上述功能捕获标签
方法多种,或者你可以这样写:/<([^>]+)>[\d\D]*<\/\1>/
四. 原理部分
回溯
就是解析的一个操作,比如/ab{1,3}c/,对abbc查找时,先找abb,再找abbb,找不到,就去找abbc,这里倒退了一个‘b’,叫它回溯
这里给了个”.*”的回溯例子
像这张图片所示,我们可以在遇到第二个双引号的时候就停下来,然而却有回溯...不如改一下代码/"[^"]*"/,意思是只要遇到第二个双引号就stop
惰性量词(?)在这里挺好用的,指尽量少的匹配
五. Javascript应用
reg.test()
测试是否包含该内容,返回一个bool变量。
var r = /\d{3}/;
var a = '123';
var b = '123ABC';
var c = 'abc';
r.test(a)//true
r.test(b) //true
r.test(c) //false
str.match()
与test()不同,不只是返回bool变量,它会返回你所匹配到的内容。
var r = /compus/
var reg = /w+/
var s = "compus, I know something about you"
r.test(s)//true
s.match(r)//["compus"]
s.match(reg) //["compus"]
这里没有使用全局//g所以只匹配一个哦
reg.exec()
这个方法可以实现匹配全局,并返回分组的结果。
reg.exec()每次调用,返回一个匹配的结果,匹配结果和分组以数组的形式返回,不断的调用即可返回下一个结果,直到返回null
var str = "Here is a Phone Number 111-2313 and 133-2311" ;
var srg = /(\d{3})[-.]\d{4}/g;
var result = srg.exec(str);
while(result !== null)
{
console.log(result);
result = srg.exec(str);
}
result包含的内容可能比想象中的多,它是一个数组,比如第一次执行,他的结果为:
["133-2311", "133", index: 36, input: "Here is a Phone Number 111-2313 and 133-2311" groups: undefined]
这里咱之前也说过了,就是那个括号分组的内容
str.split
split是将字符串按照某个字符分隔开,比如有以下一段话,需要将其分割成单词。
var s = "unicorns and rainbows And, Cupcakes"
分割成单词,首先想到的是空格隔开,于是可以用下面方式实现
var result = s.split(' ');
//["unicorns", "and", "rainbows", "And,", "Cupcakes"]
没有实现要求。因为还有一个"And,"
------正则分割线------
result = s.split(/[,\s]/);
//["unicorns", "and", "rainbows", "And", "", "Cupcakes"]
因为多了一个""
我们并不是想让它分割的依据是逗号或者空格,依据应该是逗号或空格所在的连续序列。 在原来的基础上加一个+,改成/[,\s]+/,这个含义就是一个单独的逗号,或者一个单独的空格
result = s.split(/[,\s]+/);// ["unicorns", "and", "rainbows", "And", "Cupcakes"]复制代码
六. 注意事项
1. /[-.(]/ 在符号中的连字符-放在第一位表示连字符本身,如果放在中间,表示"从..到..",比如表示a-z
2.分支也是惰性的,比如/can|candy/,去匹配字符串"candy",得到的结果是"can",因为分支会一个一个尝试,如果前面的满足了,后面就不会再试验了。分支的优先级最低!
3.元字符是要转义的!学过编程都知道吧
4.有时候没必要使用正则
Ex.判断是否有问号可以用字符串的查找函数
5. 大正则可以拆分成小正则
6. 注意考虑一些特殊情况
7. 其他的大家可以补充,我也是看了多个教程提取出来的
测试平台:
https://regex101.com/r/dmRygT/1
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
参考文章:
https://www.zhihu.com/tardis/sogou/art/30750456
https://juejin.im/post/5b5db5b8e51d4519155720d2#heading-17
https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md#1-%E5%9F%BA%E6%9C%AC%E5%8C%B9%E9%85%8D
帖子到这里就结束了,希望大家都能学会正则表达式
附件格式更整齐一些
蓝奏云 :https://www.lanzouj.com/b00z9h48j 密码:8r3y 吾爱币+1 GET {:1_896:}感觉像揍人啊,以后一定要忍到最后,直接下载全量的,方便很多啊 其实我想问一下,关于正则表达式你是怎么学习和应用的。我是前端,似乎没有太多的场景用到正则,即使有,感觉网上一搜更快。每次学习完,用的少,转眼就忘。
感谢楼主!正好最近用到 感谢你的分享 非常感谢,将三篇大作合并一起学习收藏,感谢! 三篇都看完了,受益匪浅 淡雅香 发表于 2020-2-28 18:18
三篇都看完了,受益匪浅
谢谢,有用就好{:301_1003:} 想不到今天刷到了正在学的东西,抽个时间看看,先收藏一波 谢谢分享(^O^) 好贴 收藏起来!
页:
[1]
2