为了账号安全,请及时绑定邮箱和手机立即绑定

正则十八式-第三式:龙跃于渊

正则十八式-第三式:龙跃于渊

少年,见你骨骼精奇,是百年一遇的练武奇才,你我又是有缘人,随为师修炼吧


接上篇:正则十八式-第二式:控鹤擒龙

https://img1.sycdn.imooc.com//5de226f60001141412800397.jpg

藏扇仙:"徒儿,方才确实从400多万个字符中提取出了有用信息,不过嘛..."  

捷特:"嗯...,掺杂了一些废料,师傅请宽心,待吾splite处理一下"

藏扇仙:"傻徒儿,4000多个字符串,你splite不耗时?"

捷特:"弟子愚钝,还请师傅明示。"


[壹] 金鳞困穴,龙跃于渊

1.分组:金鳞岂是池中物。

藏扇仙:"上面犹如一条龙困在池中,被杂草束缚,现在你需要发现他,并为他破除障碍..."  

捷特:"弟子该如何做?"

藏扇仙:"我们需要获取的地方是  .*  对应的部位,可以使用分组"

捷特:"也就是可以定点取?"

藏扇仙:"然也,方法很简单,加个括号就行了。"  

藏扇仙:"matcher.group(1)说明取第一分组。这样便可,龙跃于渊"

private static void regexHtml(String target) {   

 String regex="username\">(.*?)<";    

Pattern pattern = Pattern.compile(regex);    

Matcher matcher = pattern.matcher(target);    

while (matcher.find()){        

System.out.println(matcher.group(1));    } }

https://img1.sycdn.imooc.com//5de226f70001f3d712800425.jpg
2.组数

捷特:"这么说,默认是第0组。"

藏扇仙:"是的,上面如果matcher.group(0)就和原先结果一样"

捷特:"明白了,是不是多少个括号就是多少组?"

藏扇仙:"可以用matcher.groupCount()获取组数,且看下表。"

正则组数目标所在组
username\">.*?<0-
username\">(.*?)<11
(username)">(.*?)(<)32
(username)(">(.*?)(<))43

捷特:"通过我的火眼金睛发现,数左括号就行了,第几个就是第几组。"
藏扇仙:"秀儿如你,确实如此。"


3.组命名

捷特:"这1,2,3,4的,几百个组的正则,一个个数还不疯掉?"

藏扇仙:"哟,小样,还有志向写几百个组的正则?好吧,为师把看家本领交给你--组命名。"

捷特:"就是嘛,我一猜就能命名。"

藏扇仙:"在组内最前面?<Gname>就可以取名了,为了明了,为师喜欢加个G前缀。"

private static void regexHtml(String target) {   

String regex="(username)(\">(?<Gname>.*?)(<))";    

Pattern pattern = Pattern.compile(regex);    

Matcher matcher = pattern.matcher(target);    

while (matcher.find()){        

System.out.println(matcher.group("Gname"));    } }


[贰] 三千飞龙跃于渊

1.测试数据

藏扇仙:"下面是一片乱七八糟的文章,出现了很多日期,你把年月日过滤出来。"

捷特:"这个简单,看我--龙跃于渊"

https://img1.sycdn.imooc.com//5de226f70001f37112800410.jpg


2.提取日期

private static void regexToday(String target) {    

String regex="(?<Gyear>\\d{4}年)(?<Gmonth>\\d{2}月)(?<Gday>\\d{2}日)";    

Pattern pattern = Pattern.compile(regex);    

Matcher matcher = pattern.matcher(target);    

while (matcher.find()){        

System.out.println(matcher.group("Gyear"));        

System.out.println(matcher.group("Gmonth"));        

System.out.println(matcher.group("Gday"));    } }

https://img1.sycdn.imooc.com//5de226f70001fa9612800424.jpg


3.正则表达式的分析和逐步完善

藏扇仙:"正则最难的是细心观察,这里还有一些负数无法匹配。"
捷特:"我再来想办法。"

---->[正则表达式的分析]---- 原正则  (?

<Gyear>\\d{4}年)(?<Gmonth>\\d{2}月)(?<Gday>\\d{2}日) 

这只能匹配连续四个数字的年分,2个数字的月份,2个数字的日期,条件比较苛刻。 

适配   -45年1月1日 现在   (?<Gyear>-?\d{1,4}年)(?<Gmonth>\d{1,2}月)(?<Gday>\d{1,2}日) -? 

代表有没有-号都可以匹配到, 再将原来苛刻的\d{4}等放低要求\d{1,4},说明有一个数字就OK了

https://img1.sycdn.imooc.com//5de226f70001250b12800492.jpg
4.添加需求

藏扇仙:"现在粗略获取一下日期后的文字,不要求非常精确。"

捷特:"这个我来想想...简单的,加个\W+就行了只不过无法匹配到数字。"

藏扇仙:"这篇字符串本身的质量也不高,规则性不强。能配成这样已经不错了。"

(?<Gyear>-?\d{1,4}年)(?<Gmonth>\d{1,2}月)(?<Gday>\d{1,2}日)(?<Ginfo>\W+)

https://img1.sycdn.imooc.com//5de226f70001c12812800381.jpg

现在,你应该学会分组了吧,这样日期和简单的简介就能很容易捕获。
插入数据库什么的也不是难事。你get了吗?


[叁]、实战练习

曾经写过一篇:玩转字符串篇--代码自动生成,解放双手基本上都有splite来处理字符串
现在会了这第三式,原来so,easy搞一波。下面的Android自定义控件,大家应该不陌生。
需求:1.拿到类名2.拿到属性名attr3.拿到属性名对应的类型format

<?xml version="1.0" encoding="utf-8"?> 

<resources>    <declare-styleable name="TolyProgressBar">        

<attr name="z_pb_bg_color" format="color"/>        

<attr name="z_pb_bg_height" format="dimension"/>        

<attr name="z_pb_on_color" format="color"/>        

<attr name="z_pb_on_height" format="dimension"/>        

<attr name="z_pb_txt_color" format="color"/>        

<attr name="z_pb_txt_size" format="dimension"/>        

<attr name="z_pb_txt_offset" format="dimension"/>        

<attr name="z_pb_txt_gone" format="boolean"/>    </declare-styleable> </resources>

跟我一起喊:控鹤擒龙,龙跃于渊 这样就能获取原始数据,之后怎么玩都可以。

private static void regexAttr(String target) {    

String regex="<attr name=\"(?<Gattr>.*?)\".*format=\"(?<Gtype>.*?)\"";    

Pattern pattern = Pattern.compile(regex);    

Matcher matcher = pattern.matcher(target);    

while (matcher.find()){        

System.out.println(matcher.group("Gattr")+" 类型:"+matcher.group("Gtype"));    } }

对于一些模板、代码生成或字符串处理的工作,最主要的就是获取需要的字段
控鹤擒龙,龙跃于渊这两招是最基本的正则处理,当然也是最有效的实用的。


对于类名的获取同理。可以用一个Map来盛放匹配的数据以供使用


https://img1.sycdn.imooc.com//5de226f7000160f612800413.jpg

private static void regexAttr(String target) {    

Map<String,String> map =new HashMap<>();    

String regex="<attr name=\"(?<Gattr>.*?)\".*format=\"(?<Gtype>.*?)\"";    

Matcher matcher = Pattern.compile(regex).matcher(target);    

while (matcher.find()){        

map.put(matcher.group("Gattr"),matcher.group("Gtype"));    }    

String regexClass="<declare.*?\"(?<Gclass>.*?)\"";    

Matcher matcherClass = Pattern.compile(regexClass).matcher(target);    

while (matcherClass.find()){        

map.put("ClassName",matcherClass.group("Gclass"));    }    

System.out.println(map); }




点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
20
获赞与收藏
56

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消