做Web开发时,经常需要从一个消息中去取得自己需要的字段信息,如果这个消息是Json或XML类型那很方便。但如果是个字符串呢,就像下面这样:
val str = “window.code=200;window.redirect_uri=\”wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARiFc26pwMtnUC2PBuJalkaS@qrticket_0&uuid=Yaw97YVBXQ==&lang=zh_CN&scan=1492838576\”;”
以下就是我做微信机器人时遇到的其中一种情况,需要从这个字符串中获取它的状态码(200)以及跳转的uri(wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARiFc26pwMtnUC2PBuJalkaS@qrticket_0&uuid=Yaw97YVBXQ==&lang=zh_CN&scan=1492838576)
起初我不了解正则表达式,看到它这么多的表达式类型,觉得这么多东西怎么记得住,即使花时间记住了过段时间也忘了。因此我一直没有深入的去理解正则表达式。我也一直以为正则表达式都是用来匹配某个模式串是否存在的,比如检测在”hello word”中是否有hello,毕竟很多的教程一上来都是说的这个。因此我起初对于这种在字符串获取特定的值,做法都是用sprit(),比如str.sprit(“;”)(0).sprit(“window.code=”)(1)来取到200,但是这种做法非常可怕,前提是要求字符串的格式永远不变,一旦格式发生些许变化,比如code和=之间多了一个空格,结果必然是一堆报错,最常见的就是数组越界。直到我后来看到了一篇讲正则表达式的文章正则表达式30分钟入门教程
发现我们可以用分组的方式很优雅的完成上面的工作。
先直接上代码,这里面用到了java工具包中的regex
import java.util.regex.Pattern
//编程语言用的Scala,java也类似,但这里重点讲的是正则表达式pattern
val str = "window.code=200;window.redirect_uri=\"wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARiFc26pwMtnUC2PBuJalkaS@qrticket_0&uuid=Yaw97YVBXQ==&lang=zh_CN&scan=1492838576\";"
val pattern = Pattern.compile(""".*window.code *= *(\d*).*window.redirect_uri *= *"(.*)".*""")
val matcher = pattern.matcher(str)
val boolean = matcher.matches()//true or false
val code = matcher.group(1)//200
val uri = matcher.group(2)//wx.qq.com.....
我们着重来看这个正则表达式
.*window.code *= *(\d*).*window.redirect_uri *= *”(.*)”.*
我们先将这个表达式简化一下
window.code=(\d*);window.redirect_uri=”(.*)”;