Java正则表达式
正则表达式原理
底层是使用有限状态自动机,又分确定型有限状态自动机(DFA)和非确定型有限状态自动机(NFA),这两种状态机的能力是一样的,都能识别正则语言。正则表达式的识别引擎,都是基于DFA或NFA构造的。好像了解了编译原理之后才能理解得更加透彻!
正则表达式简单使用
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory
{
public static void main(String[] args) {
String content="1950年7月10日";
// 目标:匹配所有四个数字
// 1、\\d 表示一个任意的数字
String reg="\\d\\d\\d\\d";
// 2、创建一个模式对象,即正则表达式对象
Pattern pattern=Pattern.compile(reg);
// 3、创建匹配器,按照正则表达式规则去匹配content字符串
Matcher matcher= pattern.matcher(content);
//4、开始匹配
while (matcher.find())
{
System.out.println("找到了"+matcher.group(0));
}
}
}
group方法的源码
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
匹配过程中没有分组
matcher.find() 完成的任务:
(1).根据指定的规则,定位满足规则的子字符串(比如一开始的1950)
(2).找到后,将 子字符串的开始索引 (即0)记录到matcher对象属性的group数组的group[0]位置
把该子字符串的结束的索引+1 (即4) 存放到 group[1]的位置
(3).同时记录oldLast的值为子字符串结束的索引+1 的值(即4),即下次开始执行find方法时,就从4开始匹配!
匹配过程中分组
matcher.find() 完成的任务:
(1).根据指定的规则,定位满足规则的子字符串(比如一开始的1950)
(2).找到后,将 子字符串的开始索引 (即0)记录到matcher对象属性的group数组的group[0]位置
把该子字符串的结束的索引+1 (即4) 存放到 group[1]的位置
如果有分组,比如匹配规则是这样子的:(\d\d)(\d\d)
(2.1) 将成功匹配的子字符串的第一个子字符串的开始索引(即0)存放到group[2]当中;
将成功匹配的子字符串的第一个子字符串的结束索引+1(即2)存放到group[3]当中;
(2.2)将成功匹配的子字符串的第二个子字符串的开始索引(即2)存放到group[4]当中;
将成功匹配的子字符串的第二个子字符串的结束索引(即4)存放到group[5]当中
(3).同时记录oldLast的值为子字符串结束的索引+1 的值(即4),即下次开始执行find方法时,就从4开始匹配!
正则表达式语法
正则表达式——元字符
一般可以有如下分类
1、限定符
2、选择匹配符
3、分组组合和反向引用符
4、特殊字符
5、字符匹配符
6、定位符
正则表达式中——转义字符
\ 转义符号:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义字符,否则会报错。比如,要匹配的字符规则为 abc$(。如果这时候,不对等待匹配的字符串进行转义,那么就会出错!
在java中,需要用\代表其他语言中的\。
在java中,需要用到转义字符的有如下:
. * + \ / ( ) $ ? [ ] ^ { }
正则表达式——字符匹配符
符号 | 符号 | 示例 | 解释 |
---|---|---|---|
[ ] | 可接收的字符列表 | [efgh] | e、f、g、h其中的任意一个字符 |
[^] | 不可接收的字符列表 | [^abc] | 除a、b、c以外的任意一个字符 |
- | 连字符 | A-Z | 任意单个大写字母 |
. | 匹配除\n以外的任意一个字符 | a…b | 以a为开头,以b为结尾,中间包括两个任意字符 |
\\d | 匹配任意一个数字字符 | \\d{3}(\\d)? | 匹配三个数字或者四个数字的字符串 |
\\D | 匹配任意一个非数字字符,相当于[^0-9] | \\D(\\d)* | 以单个非数字字符开头,后面接任意个数字字符的字符串 |
\\w | 匹配单个数字,大写字母,小写字母,相当于[0-9A-Za-z] | \\d{3}\\w{4} | 以3个数字字符开头的长度为7的数字字母字符串 |
\\W | 匹配单个非数字,非大写字母,非小写字母字符,相当于[^0-9a-zA0-z] | \\W+\d{2} | 以至少一个非数字字母开头的,2个数字字符结尾的字符串 |
+ | 表示至少有一个字符 | ||
? | 表示0到1个字符 | ||
* | 表示任意数目的字符 | ||
(?i) | 匹配字母,并且字母忽略大小写 | (?i)abc | 匹配abc,ABC,aBc… |
\\s | 匹配任意的空白字符 | ||
\\S | 匹配任意的非空白字符,和\\s相反 |
正则表达式——匹配案例
匹配忽略大小写的abc
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory
{
public static void main(String[] args) {
String content="abc1212AbcAbC";
// 1、匹配忽略大小写的abc
String reg="(?i)abc";
// 2、创建一个模式对象,即正则表达式对象
Pattern pattern=Pattern.compile(reg);
// 3、创建匹配器,按照正则表达式规则去匹配content字符串
Matcher matcher= pattern.matcher(content);
//4、开始匹配
while (matcher.find())
{
System.out.println("找到了"+matcher.group(0));
}
}
}
找到了abc
找到了Abc
找到了AbC
匹配只忽略B的大小写的abc字符
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory
{
public static void main(String[] args) {
String content="abc1212AbcaBc";
// 1、匹配一个忽略b的大小写字符
String reg="a((?i)b)c";
// 2、创建一个模式对象,即正则表达式对象
Pattern pattern=Pattern.compile(reg);
// 3、创建匹配器,按照正则表达式规则去匹配content字符串
Matcher matcher= pattern.matcher(content);
//4、开始匹配
while (matcher.find())
{
System.out.println("找到了"+matcher.group(0));
}
}
}
找到了abc
找到了aBc
正则表达式——选择匹配符
符号 | 符号 | 实例 | 解释 |
---|---|---|---|
| | 匹配 | 前面 或者后面的内容 | ab| cd | 匹配ab 或者 cd |
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory
{
public static void main(String[] args) {
String content="abc1212AbcaBc长度cdcqdascnjjoiqdqw";
String reg="ab|cd";
Pattern pattern= Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println("找到了"+matcher.group(0));
}
}
}
找到了ab
找到了cd
正则表达式——限定符
符号 | 含义 | 示例 | 说明 |
---|---|---|---|
* | 指定字符重复0次到n次(无要求)零到多 | (abc)* | 说明包含任意个abc的字符串 |
+ | 指定字符重复1次到n次(至少一次)一到多 | m+(abc)* | 至少以1个m字母开头的后面跟着任意个abc的字符串 |
? | 指定字符重复0次或者1次(最多一次)零到一 | m+(abc)? | 至少以一个m开头,后接ab或者abc的字符串 |
{n} | 只能输入n个字符 | [abc]{3} | 由abcd这四个字母中组成的任意长度为3的字符串 |
{n,} | 指定至少n个匹配 | [abcd]{3,} | 由abcd这四个字母组成的至少长度为3的字符串 |
{n,m} | 指定至少n个但不多于m个匹配 | [abcd]{3,5} | 由abcd组成的任意长度的不小于3,不大于5的字符串 |
正则表达式——定位符
符号 | 含义 | 实例 | 说明 |
---|---|---|---|
^ | 指定起始字符 | ^ [0-9]+[a-z]* | 以至少一个数字字符开头,后面接任意个小写字母的字符串 |
$ | 指定结尾字符 | ^ [0-9]\\-[a-z]+$ | 以至少一个数字字符开头,后面连接 - 字符,并且至少以一个小写字母结尾的字符串 |
\\b | 匹配目标字符的边界 | han\\b | 这里说的有边界是指子字符串有空格,或者目标字符串的结束位置 |
\\B | 匹配目标字符的非边界 | han\\B | 和\b的含义相反 |
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory
{
public static void main(String[] args) {
String content="zidu 112321c zidu12231";
// 以至少一个数字开头,以任意个小写字母结尾的字符串
//String reg="^[0-9]+[a-z]*";
//以至少一个数字开头,至少一个小写字母结尾的字符串
//String reg="^[0-9]+[a-z]+$";
// 匹配边界的zidu
// String reg="zidu\\b";
// 匹配非边界的zidu
String reg="zidu\\B";
Pattern pattern= Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println("找到了"+matcher.group(0));
}
}
}
正则表达式——捕获分组
可以给分组取名,后来获取数据的时候,不用那么麻烦去计算第几个分组,直接利用组名来获取就ok了!
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory01 {
public static void main(String[] args) {
String content="1996年4月23日,1999年6月28日";
String reg="(?<zidu1>\\d\\d)(?<zidu2>\\d\\d)";
Pattern pattern=Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
System.out.println("第一组"+matcher.group(1));
System.out.println("第一组【通过组名来取】"+matcher.group("zidu1"));
System.out.println("第二组"+matcher.group(2));
System.out.println("第二组【通过组名来取】"+matcher.group("zidu2"));
}
}
}
1996
第一组19
第一组【通过组名来取】19
第二组96
第二组【通过组名来取】96
1999
第一组19
第一组【通过组名来取】19
第二组99
第二组【通过组名来取】99
正则表达式——非捕获分组
?: 这种写法就是非捕获分组,也就是看起来是分组,但实际上不是分组,不能使用matcher.group(1)来获取.匹配的内容是自渡一号,自渡二号,自渡三号这三个子字符串
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory01 {
public static void main(String[] args) {
String content="自渡一号自渡二号自渡三号";
// String reg="自渡一号|自渡二号|自渡三号";
// 下面这种写法就是非捕获分组,也就是看起来是分组,但实际上不是分组,不能使用matcher.group(1)来获取
String reg="自渡(?:一号|二号|三号)";
Pattern pattern=Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
}
}
}
自渡一号
自渡二号
自渡三号
?=表示匹配的内容是在后面这些字符串中有的关键字的子字符串,比如,我只想找有关于自渡一号和自渡二号中的自渡关键字,如果不是这两个子字符串中的“自渡”,我是不要的。
这里只会输出自渡一号和自渡二号中的自渡,即只有两个结果!
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory01 {
public static void main(String[] args) {
String content="自渡一号自渡二号自渡三号";
// String reg="自渡一号|自渡二号|自渡三号";
String reg="自渡(?=一号|二号)";
Pattern pattern=Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
}
}
}
自渡
自渡
?!,寻找的内容不在后面所跟着内容的字符串的子字符串里面。找到不在自渡一号,自渡二号中的“自渡关键字”
这里只会输出自渡三号中的自渡,即只有一个结果,作用跟上面的相反!
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory01 {
public static void main(String[] args) {
String content="自渡一号自渡二号自渡三号";
// String reg="自渡一号|自渡二号|自渡三号";
String reg="自渡(?!一号|二号)";
Pattern pattern=Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
}
}
}
自渡
正则表达式——非贪婪匹配
Java中的正则表达式默认是一个贪婪匹配!
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory01 {
public static void main(String[] args) {
String content="12343";
// String reg="\\d+"; //默认是贪婪匹配
String reg="\\d+?"; // 将 ? 附带在 * . + 之后,就可以修改为非贪婪匹配
Pattern pattern=Pattern.compile(reg);
Matcher matcher= pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
}
}
}
1
2
3
4
3
正则表达式——案例(核心是匹配规则)
1.验证输入的字符串是否为汉字字符串
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory02
{
public static void main(String[] args) {
// 1、等待校验的字符串
String content="要好好加油";
// 2、定义匹配规则
String reg="^[\u0391-\uffe5]+$";
// 3、定义一个匹配器对象
Pattern pattern=Pattern.compile(reg);
// 4、利用匹配器对象进行匹配
Matcher matcher= pattern.matcher(content);
// 5、获取匹配结果
if(matcher.find())
{
System.out.println("满足格式");
}
else
System.out.println("不满足格式");
}
}
2.验证该数字是否是1-9开头的6位数字
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory02
{
public static void main(String[] args) {
// 1、等待校验的字符串
String content="123125";
// 2、定义匹配规则
String reg="^[1-9]\\d{5}$";
// 3、定义一个匹配器对象
Pattern pattern=Pattern.compile(reg);
// 4、利用匹配器对象进行匹配
Matcher matcher= pattern.matcher(content);
// 5、获取匹配结果
if(matcher.find())
{
System.out.println("满足格式");
}
else
System.out.println("不满足格式");
}
}
3.验证QQ号码
1-9开头的5到10位数字
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory02
{
public static void main(String[] args) {
// 1、等待校验的字符串
String content="1194801234";
// 2、定义匹配规则
String reg="^[1-9]\\d{4,9}$";
// 3、定义一个匹配器对象
Pattern pattern=Pattern.compile(reg);
// 4、利用匹配器对象进行匹配
Matcher matcher= pattern.matcher(content);
// 5、获取匹配结果
if(matcher.find())
{
System.out.println("满足格式");
}
else
System.out.println("不满足格式");
}
}
4、验证手机号码
必须是以13,14,15,18开头的11位数字
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory02
{
public static void main(String[] args) {
// 1、等待校验的字符串
String content="13948012341";
// 2、定义匹配规则
String reg="^1(3|4|5|8)\\d{9}$";
// 3、定义一个匹配器对象
Pattern pattern=Pattern.compile(reg);
// 4、利用匹配器对象进行匹配
Matcher matcher= pattern.matcher(content);
// 5、获取匹配结果
if(matcher.find())
{
System.out.println("满足格式");
}
else
System.out.println("不满足格式");
}
}
正则表达式——三个常用类
Pattern类
验证某个字符串是否整体匹配所定义的规则!
public class PatternMethod {
public static void main(String[] args) {
String content="hello,I am gaolinhui!";
String reg="hello";
// 验证某个字符串是否整体匹配某种效果
boolean matches= Pattern.matches(reg,content);
System.out.println(matches);
}
}
Matcher类
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main
{
public static void main(String[] args) {
String content="hello edu jack tom hello smith hello";
String reg="hello.*";
reg="hello";
Pattern pattern=Pattern.compile(reg);
Matcher matcher = pattern.matcher(content);
while (matcher.find())
{
System.out.println("=============");
// 输出匹配的子字符串第一个索引位置
System.out.println(matcher.start());
// 输出匹配的子字符串的最后一个索引的位置+1
System.out.println(matcher.end());
// 输出,截取到的子字符串
System.out.println("找到"+content.substring(matcher.start(), matcher.end()));
}
// 常用于,去检验某个字符串是否符合整体某个规则
System.out.println(matcher.matches());
// 完成如果content,有edu则替换为zidu
reg="edu";
pattern=Pattern.compile(reg);
matcher=pattern.matcher(content);
// 返回新的字符串才会改变,
String newString =matcher.replaceAll("zidu");
// 原先的不变
System.out.println(content);
System.out.println(newString);
}
}
正则表达式——分组、捕获,反向引用
正则表达式——分组
我们可以使用圆括号组成一个比较复杂的匹配模式,那么一个圆括号我们可以看做是一个子表达式/一个分组!
正则表达式——捕获
把正则表达式中子表达式/分组匹配的内容,保存到内存中一数字编号或者显式命名的组里,方便以后引用,从左向右,以分组的左括号为标志,第一个出现的分组的组合为1,第二个为2,以此类推。组0代表的是整个表达式!
反向引用
圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称之为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用 \\分组号,外部反向引用 $分组号!
反向引用案例
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main
{
public static void main(String[] args) {
String content="155555214146644849522346113354";
// 寻找两个连续相同的数字
String reg="(\\d)\\1";
// 匹配五个连续相同的数字
reg="(\\d)\\1{4}";
// 匹配个位与千位相同,十位与百位相同的数字
reg="(\\d)(\\d)\\2\\1";
Pattern pattern=Pattern.compile(reg);
Matcher matcher = pattern.matcher(content);
while (matcher.find())
{
System.out.println(matcher.group(0));
}
}
}
商品码案例
匹配一个商品码,前五位是数字,后面一个横杠-,然后后面九位数字,并且三位数字连续且相同。
String reg="(\\d){5}-(\\d)\\2{2}(\\d)\\3{2}(\\d)\\4{2}";
结巴程序
import org.bouncycastle.tsp.TSPUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
*
* 结巴程序
*
* */
public class Main
{
public static void main(String[] args) {
String content="我...我要....学学学学...编程Java!";
System.out.println(content);
System.out.println("====>");
//1.把.去掉
Pattern pattern = Pattern.compile("\\.");
Matcher matcher = pattern.matcher(content);
content=matcher.replaceAll("");
// System.out.println(content);
// 2.去掉重复的字符
pattern=Pattern.compile("(.)\\1+");
matcher=pattern.matcher(content);
// while (matcher.find()) System.out.println(matcher.group(0));
// 外部替换,将重复的字符,用找到的第一个分组去替换
content=matcher.replaceAll("$1");
System.out.println(content);
}
}
我...我要....学学学学...编程Java!
====>
我要学编程Java!
// 最后的几个部分也可以用这个方法!就节省代码
content=Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
正则表达式——在String类中使用
public class Main
{
public static void main(String[] args) {
String content="2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布," +
"几周后其获得了Apple公司Mac OS X的工业标准的支持。2001年9月24日," +
"J2EE1.3发布。2002年2月26日,J2SE1.4发布。自此Java的计算能力有了大幅提升,与J2SE1.3相比," +
"其多了近62%的类和接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持" +
"(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日志与断言。" +
"2004年9月30日,J2SE1.5发布,成为Java语言发展史上的又一里程碑。" +
"为了表示该版本的重要性,J2SE 1.5更名为Java SE 5.0(内部版本号1.5.0)," +
"代号为“Tiger”,Tiger包含了从1996年发布1.0版本以来的最重大的更新,其中包括泛型支持、" +
"基本类型的自动装箱、改进的循环、枚举类型、格式化I/O及可变参数。";
content=content.replaceAll("JDK1\\.3|JDK1\\.4","JDK");
System.out.println(content);
String conten1="13921414648";
boolean isPhoneNumber = conten1.matches("(138|139)[0-9]{8}");
if (isPhoneNumber)
System.out.println("正确手机号码");
else
System.out.println("错误手机号码");
// 按照 # 或者 - 或者 ~ 或者数字 来进行分割
String content2="hello#daqewq-wedfwe~wedw1cds";
String[] split = content2.split("#|-|~|\\d");
for (String s : split) {
System.out.println(s);
}
}
}
正则表达式——常用表达式
1.校验数字的表达式
数字:^[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]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
校验字符的表达式
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符[^~\x22]+
================================================= 特殊使用========================================
.*匹配除 \n 以外的任何字符。
/[\u4E00-\u9FA5]/ 汉字
/[\uFF00-\uFFFF]/ 全角符号
/[\u0000-\u00FF]/ 半角符号
特殊需求表达式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\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}$
电话号码("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位、18位数字):^\d{15}|\d{18}$
短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\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)$
钱的输入格式
1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
9.xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
10.中文字符的正则表达式:[\u4e00-\u9fa5]
11.双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
12.空白行的正则表达式:\n\s*\r (可以用来删除空白行)
13.HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
14.首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
15.腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
16.中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
17.IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
18.IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
19.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地址时有用)
20.校验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]))
21.子网掩码:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
22.校验日期:^(?:(?!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“ 格式的日期校验,已考虑平闰年。)
23.抽取注释:<!--(.*?)-->
24.查找CSS属性:^\\s*[a-zA-Z\\-]+\\s*[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}
25.提取页面超链接:(<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?', $follow_list).'))[^" rel="external nofollow" ]+)"((?!.*\\brel=)[^>]*)(?:[^>]*)>
26.提取网页图片:\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*)
27.提取网页颜色代码:^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
28.文件扩展名效验:^([a-zA-Z]\\:|\\\\)\\\\([^\\\\]+\\\\)*[^\\/:*?"<>|]+\\.txt(l)?$
29.判断IE版本:^.*MSIE [5-8](?:\\.[0-9]+)?(?!.*Trident\\/[5-9]\\.0).*$
正则表达式——总结
正则表达式很强大,可以帮助我们快速处理文本!只能是根据我们自己的实际业务需求来编写正则表达式的规则,希望能有所提升!