【野路子】正则表达式~极速入门图文教程
【野路子】正则表达式~极速学习 本教程适合正则新手、初学者、看完能就用的人群。 怎么入门呢?网上的教程太多太多了,零散的也比较多,视频教程看起来更佳。但是整个过程比较漫长枯燥,可能暂时和你的需求目标不太一致,有些学不致用的样子。或者是问人、问百度最后搞出来了,可到了下次需要用到的时候,又进入萌逼状态了。 正则表达式是一个什么东西呢?如果你停留在这个问题上,这个教程可能对你作用不大。需要了解的话,详细查阅百科。 这里只说一点:正则表达式在很多计算机程序设计语言上都可以进行匹配字符串的一种模式。 往往用到的情况如下:数据校验、采集程序、爬虫程序,或者说我就想从目标数据拿到我想要的信息。 开始了如果你做好准备了,那么以下将以常用的两种语言进行讲述。 Js、PHP 首先来看个例程: 1.获取开源中国首页基本信息https://www.oschina.net/ 如:title、description、keywords 怎么获取源码就不说了,右键查看源代码等,类似问题后面不再提起。 a.匹个title 入个门在线测试正则表达式地址:http://tool.oschina.net/regex/ 可以看到源码中的目标数据如横线所标。我们只需要匹配到对应的内容即可以。 首先将对应的数据信息包括固定数据原本复制出来。 标题:<title>开源中国 - 找到您想要的开源项目,分享和交流</title> 描述:<meta name="description" itemprop="description" content="开源中国 www.oschina.net 是目前中国最大的开源技术社区。我们传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。,开源中国社区"> 关键词:<meta name="keywords" content="开源,OSC,开源软件,开源硬件,开源网站,开源社区,java开源,perl开源,python开源,ruby开源,php开源,开源项目,开源代码"> 举例测试标题,复制到在线测试正则里面进行调试。 很显然我们匹配到结果了,这个正则表达式中可以认为不存在任何 正则表达式的语法,刚才的过程只是相当于 正常的字符串匹配。 我们继续,删除部分数据(删除可变的数据),用正则表达式语法代替。 正则表达式的书写原则也就是:用正则语法替换可变的数据
根据这个,那么我们将其中的内容替换下。 <title>开源中国 - 找到您想要的开源项目,分享和交流</title> 改为: <title>开源中国s-s找到您想要的开源项目,分享和交流</title> 测试是否能匹配通过。 很显然,我们匹配到了。继续改进。 其中的中文字符以及逗号都是属于 “非空格”,所以我们可以通过S代替。继续替换并测试。 <title>开源中国s-s找到您想要的开源项目,分享和交流</title> 改为: <title>SSSSs-sSSSSSSSSSSSSSSSS</title> 依然能匹配到,貌似有些乱,容易出错,我们继续改进。
此时终于可以将那一堆S代替了,简直美观。 <title>SSSSs-sSSSSSSSSSSSSSSSS</title> 改为: <title>S+s-sS+</title> 或 <title>S*s-sS*</title> 或 <title>S{4}s-sS{16}</title> 除此之外还有方法匹配到吗? 当然,如 <title>开源中国 - 找到您想要的开源项目,分享和交流</title> 例1: <title>[u4e00-u9fa5]+s-s[u4e00-u9fa5]+,[u4e00-u9fa5]+</title> 例2: <title>[^<]+</title> 普及下语法:
上面第一个正则,很显然不需要解释,[u4e00-u9fa5] 这个组合是匹配中文字符的,+就是进行多个匹配。 第二个正则很简洁,什么意思呢。 [<] 只匹配 < (左键括号) [^<] 这里的^(非逻辑)起到的作用让这个组合变成了,只匹配 非< ,也就是说只要不是< 都可以匹配。 [^<]+ 多次匹配,直到将非<字符匹配完停止。 <title>[^<]+</title> 此时再看这个式子,很明显了,将两个title 标记中间的所有内容匹配完,也就是我们需要的内容。 b. 描述信息如何匹配?原本数据: <meta name="description" itemprop="description" content="开源中国 www.oschina.net 是目前中国最大的开源技术社区。我们传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。,开源中国社区"> 经过以上的学习,我们可以书写几个式子,如 式1: <meta name="description" itemprop="description" content="[^"]+"> 式2: <metas+name="description"s+itemprop="[^"]+"s+content="[^"]+"> 式3:(错误) <metas+name="[^"]+"s+itemprop="[^"]+"s+content="[^"]+"> 以上3个式子,第一个第二个都很容易理解,仔细看就能看明白。 为什么第三个式子错了呢?他不能匹配数据吗?答案是可以的。 在书写正则表达式的过程中,往往不要忘了我们的目的,以及降低可错性。 我们举例下,第三个式子可能会匹配到什么数据? 式3: <metas+name="[^"]+"s+itemprop="[^"]+"s+content="[^"]+"> 数据1: <meta name="description" itemprop="description" content="开源中国 www.oschina.net 是目前中国最大的开源技术社区。我们传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。,开源中国社区"> 数据2: <meta name="robots" itemprop="robots" content="index,follow"> 数据3: <meta name="viewport" itemprop="viewport" content="width=device-width,initial-scale=1"> 以上三条数据,数据1是我们的意愿数据,但2和3不是,这就产生出错了。这并不是我们所想要的。 上面的数据只是举例测试,不是开源中国的数据。 所以在写正则的时候,一定要有标志性的固定字符,如上面的name="description" c.匹配关键词这里都不用写式子了,相信各位都可以很轻易的完成。 原本数据: <meta name="keywords" content="开源,开源代码"> 式子: <metas+name="keywords"s+content="[^"]+"> d.用代码实现使用chrome 打开开源中国,按F12 DevTools调试,选择Console控制台执行JS。 js var html = document.documentElement.outerHTML; html.match(/<title>[^<]+</title>/); //注意上面 </title> 多了一个反斜杠 ,我们要将正斜杠/ 转义掉,否则影响正则表达式。 //两边的 /是什么呢?这个是正则表达式的定界符,表示中间的内容为正则主要匹配数据、模式。 结果里面包含了title标签,也就是固定字符,这并不是我们的预期,如何解决呢?
修正代码 html.match(/<title>([^<]+)</title>/); html.match(/<title>([^<]+)</title>/)[1]; 测试如下 很简单就取到我们的结果。 JS的另一种写法: var regular = new RegExp('<title>([^<]+)</title>'); html.match(regular); PHP <?php $html = file_get_contents('https://www.oschina.net/'); $pattern = '/<title>([^<]+)</title>/'; preg_match_all($pattern,$html,$result); echo '<pre>'; print_r($result); 2.练习,匹配开源中国资讯条目JS html.match(/<div class="box vertical news">[^<]+<as+class="[^"]+"s+href="([^"]+)"[^>]+>([^<]+)</a>[^<]+<spans+class="box-fr news-date">([^<]+)</span>s+</div>/) 很不巧的是,智能匹配到1个,那么剩下的数据为什么没有匹配到呢? 因为match这个函数默认只返回第一次匹配的结果,不会返回所有匹配到的结果。
修饰符用法: / 正则表达式 /修饰符 如: /<li[^>]+>([^<]+)</li>/g 全文匹配所有li 如以下即可匹配到所有的条目。 html.match(/<div class="box vertical news">[^<]+<as+class="[^"]+"s+href="([^"]+)"[^>]+>([^<]+)</a>[^<]+<spans+class="box-fr news-date">([^<]+)</span>s+</div>/g); PHP <?php $html = file_get_contents('https://www.oschina.net/'); $pattern = '/<div class="box vertical news">[^<]+<as+class="[^"]+"s+href="([^"]+)"[^>]+>([^<]+)</a>[^<]+<spans+class="box-fr news-date">([^<]+)</span>s+</div>/'; preg_match_all($pattern,$result); echo '<pre>'; print_r($result); 而对于PHP而言,就不需要g了,区别于函数的选择上。 perg_match 单次匹配 preg_match_all 所有匹配 补充学习通过以上的学习,一些简单基本的正则匹配都可以实现。 那么再补充说一说常规数据校验匹配的案例,虽然网上都有。 /^d{11}$/ 匹配11位数字(手机号)
/^110[0-9]{14}[0-9xX]/ /^110[0-9]{14}[0-9X]/i 匹配北京市的身份证号,110开头,最后一位可能为数字可能为X。两个式子都可以,区别于尾部x的大小写问题,可以写到模式里,可以写到修饰符里。
/[A-z_d]+.(jpg|png|exe)/i 文件名匹配
(.*?) 所谓的万能正则 + 贪婪模式
var string = 'aa<div>test1</div>bb<div>test2</div>cc'; string.match(/<div>.*</div>/); string.match(/<div>.*?</div>/); 可以看到,第一个正则没有加? 导致执行匹配到最后一个div,而增加?的只是匹配到对等的第一个div。 这个也就是正则的贪婪模式,贪婪匹配到最后一个,加上?将取消贪婪模式,也就是非贪婪模式,默认匹配到第一个就停止。 PHP中可以使用修饰符 大写U,来取消贪婪模式,如:/<div>.*</div>/U 模式修正符 PHP模式修饰符又叫模式修正符,是在正则表达式的定界符之外使用。主要用来调整正则表达式的解释,提扩展了正则表达式在匹配、替换等操作的某些功能,增强了正则的能力。
整理总结[a-z] //匹配所有的小写字母 [A-Z] //匹配所有的大写字母 [a-zA-Z] //匹配所有的字母 [A-z] //匹配所有大小写字母 以及 []^_' 这些玩意,详查ASCII字符表。 [0-9] //匹配所有的数字 [0-9.-] //匹配所有的数字,句号和减号 [ frtn] //匹配所有的白字符 d //匹配一个数字字符。等价于 [0-9]。 D //匹配一个非数字字符。等价于 [^0-9]。 n //匹配一个换行符。等价于 x0a 和 cJ。 r //匹配一个回车符。等价于 x0d 和 cM。 s //匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。 S //匹配任何非空白字符。等价于 [^ fnrtv]。 t //匹配一个制表符。等价于 x09 和 cI。 //转义符,如果匹配字符,需使用 。 . //匹配除过"n"之外的任何字符。 ? //匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 + //匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 * //匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 ^ //匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 'n' 或 'r' 之后的位置。 $ //匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 'n' 或 'r' 之前的位置。 #修饰符 i //忽略大小写 s //忽略换行,当做一行匹配 U //非贪婪模式 上面整理了一些简单常用的,元字符以及模式规则,这些东西可以不用一次记住,书写的时候随时来查阅参考即可,写的多了,自然就会掌握这些规则技巧,完全不用刻意记。 本文引用: PHP正则表达式模式修饰符详解 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |