正则表达式,新手见它的感觉就是“这都什么玩意,乱七八糟的,完全不知所云”,但学会它就会体验那种一行代码抵数十上百行,效率飞起的感觉,简直不要太爽。今天小肆先把我自己收藏的一些正则表达式写法分享给大家,当然想深入学习如何写正则表达式,可以去w3c看看教程。
干货
一.校验数字
- 数字:
^[0-9]*$
- n位的数字:
^\d{n}$
- 至少n位的数字:
^\d{n,}$
- m-n位的数字:
^\d{m,n}$
- 零和非零开头的数字:
^(0|[1-9][0-9]*)$
- 非零开头的最多带两位小数的数字:
^([1-9][0-9]*)+(.[0-9]{1,2})?$
- 带1-2位小数的正数或负数:
^(\-)?\d+(\.\d{1,2})?$
- 正数、负数、和小数:
^(\-|\+)?\d+(\.\d+)?$
- 有两位小数的正实数:
^[0-9]+(.[0-9]{2})?$
- 有1~3位小数的正实数:
^[0-9]+(.[0-9]{1,3})?$
- 非零的正整数:
^[1-9]\d*$
- 非零的负整数:
^\-[1-9][]0-9"*$
- 非负整数:
^\d+$
- 非正整数:
^-[1-9]\d*|0$
- 非负浮点数:
^\d+(\.\d+)?$
- 非正浮点数:
^((-\d+(\.\d+)?)|(0+(\.0+)?))$
- 正浮点数:^[1-9]d.d|0.d[1-9]d$
- 负浮点数:
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$
- 浮点数:
^(-?\d+)(\.\d+)?$
二.效验字符
- 汉字:
^[\u4e00-\u9fa5]{0,}$
- 英文和数字:
^[A-Za-z0-9]+$
- 长度为3-20的所有字符:
^.{3,20}$
- 由26个英文字母组成的字符串:
^[A-Za-z]+$
- 由26个大写英文字母组成的字符串:
^[A-Z]+$
- 由26个小写英文字母组成的字符串:
^[a-z]+$
- 由数字和26个英文字母组成的字符串:
^[A-Za-z0-9]+$
- 由数字、26个英文字母或者下划线组成的字符串:
^\w+$
- 中文、英文、数字包括下划线:
^[\u4E00-\u9FA5A-Za-z0-9_]+$
- 中文、英文、数字但不包括下划线等符号:
^[\u4E00-\u9FA5A-Za-z0-9]+$
- 可以输入含有
^%&',;=?$\"
等字符:[^%&',;=?$\x22]+
- 禁止输入含有~的字符:
[^~\x22]+
四.特殊需求表达式
- Email地址:
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
- 手机号码:
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$
(国内 13、15、18开头的手机号正则表达式,可根据目前国内收集号扩展前两位开头号码) - 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):
^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
- 国内电话号码(0511-4405222、021-87888822):
\d{3}-\d{8}|\d{4}-\d{7}
- 身份证号(15位):
^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$
- 身份证号码(18位):
^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$
- 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
- 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
^[a-zA-Z]\w{5,17}$
- 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-16之间):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}$
- 日期格式:
^\d{4}-\d{1,2}-\d{1,2}
- 一年的12个月(01~09和1~12):
^(0?[1-9]|1[0-2])$
- 一个月的31天(01~09和1~31):
^((0?[1-9])|((1|2)[0-9])|30|31)$
- xml文件:
^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
- 中文字符的正则表达式:
[\u4e00-\u9fa5]
- 双字节字符:
[^\x00-\xff]
(包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)) - 空白行的正则表达式:
\n\s*\r
(可以用来删除空白行) - 首尾空白字符的正则表达式:
^\s*|\s*$
或(^\s*)|(\s*$)
(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式) - 腾讯QQ号:
[1-9][0-9]{4,11}
(腾讯QQ号从10000开始) - 中国邮政编码:
[1-9]\d{5}(?!\d)
(中国邮政编码为6位数字) - IP-v4地址:
\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b
(提取IP地址时有用) - 校验IP-v6地址:
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
- 子网掩码:
((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
- 校验日期:
^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$
(“yyyy-mm-dd“ 格式的日期校验,已考虑平闰年。) - 抽取注释:
<!--(.*?)-->
- 查找CSS属性:
^\\s*[a-zA-Z\\-]+\\s*[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}
- 提取页面超链接:
(<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?', $follow_list).'))[^"]+)"((?!.*\\brel=)[^>]*)(?:[^>]*)>
- 提取网页图片:
\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*)
- 提取网页颜色代码:
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
- 文件扩展名效验:
^([a-zA-Z]\\:|\\\\)\\\\([^\\\\]+\\\\)*[^\\/:*?"<>|]+\\.txt(l)?$
- 判断IE版本:
^.*MSIE [5-8](?:\\.[0-9]+)?(?!.*Trident\\/[5-9]\\.0).*$
-
前言
只有光头才能变强。
文本已收录至我的GitHub仓库,欢迎Star: https://github.com/ZhongFuCheng3y/3y
估计大家也可能听过Docker这项技术(在论坛上、招聘技能上、交流群上等等),要是不了解Docker,都不好意思在网上冲浪的时候吹牛逼了。
所以这几天学了一下Docker,总结了Docker入门的相关知识,分享给大家(好让我们一起吹牛逼)。
I need a doctor,call me a doctor. I need a doctor, doctor, to bring me back to life .
一、为什么需要Docker
官方介绍(中文版):http://www.docker-cn.com/what-docker#/developers
Docker 是世界领先的软件容器平台。
开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。
企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。1.1环境(切换/配置)麻烦
一般我们写程序的,能接触到好几个环境:
- 自己写代码的环境叫做开发环境。
- 给测试去跑的环境叫做测试环境。
- 测试完可以对外使用的叫做生产环境。
-
其实我们在学习编程中,很多时间都浪费在“环境”上:
- 如果我现在重装了系统,我想要跑我的
war/jar
包,我得去安装一下JDK、Tomcat、MySQL等配置各种的环境变量才能跑起来。 - 开开心心地跟着博主给出的步骤去写Demo,但总是有Bug。(这里我将版本/依赖也归纳在环境的范畴里边)。
- 好不容易在测试环境下跑起来了,在生产环境就各种出错!
- 跟着教学视频做分布式/集群的项目,跑一堆的虚拟机,每个虚拟机都要安装对应的环境。
-
所以就有个笑话《千万不要跟程序员说,你的代码有bug》:
- 他的第一反应是你的环境有问题,第二就是你是傻逼不会用吧。
- 你要跟他这么说:“这个程序运行的怎么运行的跟预期不一样,是我操作有问题吗?”。
- 这货就会第一反应“我擦,这是不是出bug了?”
-
1.2应用之间需要隔离
比如我写了两个应用(网站),这两个应用部署在同一台服务器上,那可能会出现什么问题?
- 如果一个应用出现了问题,导致CPU占100%。那另一个应用也会受到关联,跟着一起凉凉了。
- 这两个应用是完全不同技术栈的应用,比如一个
PHP
,一个.NET
。这两个应用各种的依赖软件都安装在同一个服务器上,可能就会造成各种冲突/无法兼容,这可能调试就非常麻烦了。 -
二、Docker是如何解决上述的问题的
2.1解决环境(切换/配置)
不知道大家有没有装过系统,比如说装Linux虚拟机,重装Windows系统,都是需要镜像的。
有了这个镜像,我们就可以运行这个镜像,来进行安装系统的操作(此处省略N个下一步),于是我们的系统就装好了。一般来说,我们去官方渠道下载的镜像,都是纯净的。比如去官方下载Windows镜像,装完后之后桌面只有一个回收站。
但有过了解装系统的同学可能就会知道,有的镜像装完可能还有360这些软件,但系统的的确确是变了。简单来说,就是这些镜像添加了其他的东西(比如360软件、腾讯、千千静听等等软件)。
Docker也是这种思路,可以将我们的想要的环境构建(打包)成一个镜像,然后我们可以推送(发布)到网上去。想要用这个环
境的时候,在网上拉取一份就好了。有了Docker,我们在搭环境的时候,跟以前的方式就不一样了。
- 之前:在开发环境构建出了一个war包,想跑到Linux下运行。我们得先在Linux下载好Java、Tomcat、MySQL,配置好对应的环境变量,将war包丢到Tomcat的webapps文件夹下,才能跑起来。
- 现在:在Linux下直接拉取一份镜像(各种环境都配好了),将镜像运行起来,把war包丢进去就好了。
-
将Docker的镜像运行起来就是一两秒的事情而已,十分方便的。
2.2解决应用之间隔离
说到这里,就得提出一个大家可能不认识的概念:LXC(Linux Containers)--->Linux容器。
2.2.1Linux容器
在Linux内核中,提供了 cgroups功能,来达成资源的区隔化。它同时也提供了名称空间( namespace)区隔化的功能, 使应用程序看到的操作系统环境被区隔成独立区间,包括进程树,网络,用户id,以及挂载的文件系统。
简单来说就是:LXC是一个为Linux内核包含特征的用户接口。通过强大的API和简单的工具,它可以让Linux用户轻松的创建和托管系统或者应用程序容器。
2.2.2回到Docker
我们在翻看Docker的官方文档的时候,也很容易看见cgroup和namespace这两个名词:
来源维基百科:
Early versions of Docker used LXC as the container execution driver, though LXC was made optional in v0.9 and support was dropped in Docker v1.10.
lxc是早期版本docker的一个基础组件,docker 主要用到了它对 Cgroup 和 Namespace 两个内核特性的控制。新的Docker版本已经移除了对LXC的support。
2.2.3Docker在Windows和Mac
上面说了,Docker底层用的Linux的cgroup和namespace这两项技术来实现应用隔离,那Windows和Mac用户能用Docker吗?
-
之前,Windows和Mac使用Docker实际上就是跑了一层Linux虚拟机。
- 比如在Windows下安装的是
Docker Toolbox
,它需要Oracle Virtual Box
来跑Docker
- 比如在Windows下安装的是
-
现在,Windows和Mac都已经原生支持Docker了。但需要一些安装的条件,详情可以查看官网
- 比如Windows:
Docker for Windows requires 64bit Windows 10 Pro and Microsoft Hyper-V
- 比如Windows:
-
参考资料:
-
Windows 原生 Docker 正式商用
-
三、虚拟机和Docker
说到应用隔离和镜像,我就想起了 虚拟机。今年下半年(此处省略.....),文体两开花(此处省略.....),要是我写文章写得不好,我是需要向XX谢罪的。
估计大家都用过虚拟机,虚拟机也能实现对应用的隔离,安装特定的镜像也能跑出我们想要的环境。虚拟机已经发展了很久了,为什么我们还需要Docker呢?
这部分内容在官网也有相关的介绍:
- http://www.docker-cn.com/what-container#/virtual_machines
-
一句话总结:Docker容器比虚拟机轻量多了!
最后
Docker可以干嘛?
- 将一整套环境打包封装成镜像,无需重复配置环境,解决环境带来的种种问题。
- Docker容器间是进程隔离的,谁也不会影响谁。
-
其实这篇文章主要是讲为什么我们需要Docker(在学习一项技术之前,必须要知道这项技术是用来干嘛的),Docker的一些概念和命令我还没介绍(留到下一篇啦)。如果还没看过【生活现场】从搬家到容器技术docker应用场景解析,可以先去看看~
前一节我们明白了maven是个什么玩意,这一节就来讲讲他的一个重要的应用场景,也就是通过maven将一个ssh项目分割为不同的几个部分独立开发,很重要,加油
--WH
一、maven父工程与子模块的拆分与聚合原理
问题描述:将ssh工程拆分为多个模块开发
1.1、拆分原理
创建一个maven project(pom),然后在创建三个子模块(maven moudule),其中三个子模块,分别为 dao、service、web,也就是将三层的内容分别独立为一个项目,进一步将耦合性降低,其中如何将他们连接起来了,看下图。
为什么需要创建parent父工程来管理其下三个子模块呢?并让其子模块继承他呢?
继承是为了消除重复,如果将dao、service、web分开创建独立的工程则每个工程的pom.xml文件中的内容存在重复,比如:设置编译版本、锁定spring的版本的等,可以将这些重复的配置提取出来在父工程的pom.xml中定义
将三层都独立分开来了,web层如何调用service层代码?service层又如何调用dao层的代码呢?
这个在没有maven之前是不可以这样做的,但是有了maven一切都不一样了,web层调用service层的代码其实很简单,因为service是一个完整的项目,那么我们在web层这个项目中想要使用别得项目中的代码,只需要通过maven的pom.xml文件编写对应的坐标,将其jar包加入进来即可达到目的,因此,看图中,ssh-web依赖ssh-service,ssh-service依赖ssh-dao,其中的原理就是我说的这样,所以才能将这三层分开成独立的项目,并且进一步抽取其公有依赖的jar包,统一交由父工程来管理,这就maven带来的效果。
1.2、聚合原理
项目开发通常是分组分模块开发,每个模块开发完成要运行整个工程需要将每个模块聚合在一起运行,比如:dao、service、web三个工程最终会打一个独立的war运行
二、案例实现
问题描述:使用maven将ssh项目进行分模块,并且实现从web到dao层的数据的存取进行实验
2.1、创建maven-parent父模块
点击next
点击next
创建好之后的父工程如图
从它的目录结构可以看出,父工程本身不写代码,它里面有一个pom.xml文件,这个文件可以将多个子模块中通用的jar所对应的坐标,集中在父工程中配置,将来的子模块就可以不需要在pom.xml中配置通用jar的坐标le、
在父工程的pom.xml中抽取一些重复的配置的,比如:锁定jar包的版本、设置编译版本等,一般这种都不需要我们自己临时配置,网上或者公司都有已经写好了的,每次使用就直接丢过来即可。下面给一个我收藏的额。嘿嘿
maven父工程整合ssh通用的pom.xml配置
2.2、创建maven-dao子模块
点next进入如下图
点击next,如下图
点击finish,完成,查看父工程中的pom.xml文件
查看ssh_dao中的pom.xml文件,会发现多了一个 parent结点,并且内部所包含的结点,其实就是父工程的坐标
查看ssh_dao的目录结构
因为是在dao层,和数据库打交道,那么就在这个项目中,需要配置hibernate.hbm.xml和hibernate.cfg.xml,但是又集成了spring,所以hibernate.cfg.xml就不需要了,添加applicationContext.xml即可(这里需要有spring整合hibernate的基础)
注意:将applicationContext.xml拆分出一个applicationContext-dao.xml,此文件中只配置dao
aplicationContext-dao.xml
jdbcinfo.properties
其他几个Student.java这些就不用看了,太简单了。
StudentTest.java这个需要讲解一下,因为这里使用junit测试的时候,会报错,报的错误是找不到junit的jar包,这里我们就会很疑惑,为什么会找不到该jar包呢,不是在父工程里面都导入了junit的jar包了吗?这里出错的原因是传递依赖的范围问题。
将父工程看做A项目(下面简称A),将该子模块ssh_dao看做B项目(下面简称B),A依赖junit的jar包是直接依赖。B继承A(实际操作就是B中填写A的坐标)也可以看成一种依赖,那么就是这样一种关系,B 依赖 A 依赖 junit, A依赖junit是直接依赖没错,那么B跟junit的关系就叫做传递(间接)依赖,我们知道A依赖的junit时,junit的jar包可以设置在A中的使用范围,就是scope属性,可以为compile,test等,而junit设置的是test,只在A中测试的时候用,那么B想用junit时,junit的作用范围是不是也是test呢?这就有一种关系。具体看表。
按照刚才上面的例子,来看看在B中,junit的作用范围是什么?首先看B 依赖 A,直接依赖,并且A在B中的作用范围是compile(没设置就默认),所以在直接依赖这一列中找到compile这一行,也就是用红色框框框起来的一行,然后B 依赖 junit,对A来说,A 是传递依赖 junit,这时候看junit设置的作用范围是多少(也就是看junit在B中的使用范围是什么)?看传递依赖这一行,junit设置的是test,找到test这一列,看相交的地方,是空的,则说明,junti在B中的test范围不能够使用,其实看图,B中任何范围内都不能够使用junit,这样你就理解了这张图是什么意思。这只是原理,实际上我们解决这种问题的时候,用一个简单粗暴的解决方案。什么jar包丢失了,我们就再次导入一次jar包即可。
所以在ssh_dao子模块的pom.xml中有junit的坐标才能使用test
2.3、创建ssh_service子模块
方法同ssh_dao模块创建方法一样,模块名称为ssh_service。
看ssh_service和ssh_parent的pom.xml文件,会出现和ssh_dao创建时一样的情况,ssh_service多出一个parents结点,ssh_parent多个一个module结点
在ssh_service的pom.xml中添加两个依赖
然后编写service层的代码,
主要关注一下applicationContext-service.xml中的事务的相关代码
aplicationContext-service.xml
该层的测试,需要将ssh_dao中的applicationContext-dao.xml将ssh_service的applicationContext-service.xml包含进去才能够实验的通。这里不做测试,
2.4、创建ssh_web子模块
方法同maven-dao模块创建方法,模块名称为ssh-web,注意:打包方式为war,而不再是jar包了,因为该层需要放到tomcat中去。与浏览器交互,就是web项目了,所以打成war包
和前面一样,ssh_parent的pom.xml中增加一个module结点,而ssh_web的pom.xml中增加一个parent结点
这个也很简单,就是跟写普通的struts2是一样的,只不过是和spring的结合,有什么对象,都通过spring来给予,并且这里多做一个事情,就是将之前的applicationContext配置文件进行结合,看下图
application.xml
web.xml中配置struts2的拦截器和spring的监听器
web.xml
这里注意一个问题,struts跟spring整合的时候,Struts.xml中的class应该填写spring配置文件中的id。
2.5、总结与启动
父工程和子模块都写完之后,就成这样了
运行调试即可。这里我遇到一个小问题,一直解决不了,
三、总结
理解了这个分模块与聚合的作用,并且知道如何开发即可。加油。确实搞的有点烦躁。