JAVA正则表达式使用总结
一、基础
1.*代表{0,} +代表{1,} ?代表{0,1}
[0-9]+=[0-9]{1,} 表示匹配0~9中的任意数字,并且至少1位。
[0-9]*=[0-9]{0,} 表示匹配0~9中的任意数字,并且可以是0位(不存在)。
[0-9]?=[0-9]{0,1} 表示匹配0~9中的任意数字,并且只能是0位或1位。
如果至少需要2位数,最多8位数,即([0-9]{2,7}) 。
不写*、+、?和{m,n}表示只能出现一次
2.^的作用
只要是”^”这个字符是在中括号”[]”中被使用的话就是表示字符类的否定,如果不是的话就是表示限定开头
^A 会匹配"Axx"中的A,但是不会匹配"xxA"中的A ---限定开头
[^a] 表示“匹配除了a的任意字符”。
3.$的作用
$表示限定结束
4.(.*?)详解
.是任意字符
.?的意思是尽可能少的匹配(?跟在限制符后表示限制符的非贪婪模式)
(.?)设置分组,如果替换、获取,可以用$1参数代替
二、示例探析
【1】
^\\s*select\\s[\\s\\S]*$
解释:
^表示限定开头,(即表示开头必须是\\s)
^\\s*则表示什么都不能有,除了空格(\\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格)
select表示含有该字符
[\\s\\S]*表示所有字符都可以有,加了*表示可以出现0次(即可以什么都没有),不加则必须有任意字符,不能什么都没有(\\S表示除空白符的所有字符,加上\\s就表示所有字符)
[\\b\\B]同上
.
也表所有字符,不过没有\\s\\S多
$表示限定结束,(即表示结束必须是[\\s\\S]*)
【2】
^\\s*select\\s+count\\s*\\(\\s*(?:\\*|\\w+)\\s*\\)[\\s\\S]*$
解释:
^\\s*select 表示开头必须是空白符或者空白符出现0次(即开头就是select)
\\s+ 表示空白符至少一次
\\(表示单纯的左括号(只是被转义了)
\\( \\s*(?:\\*|\\w+)\\s* \\)表示括号里可以两边是空白符或没有;中间的(?:\\*|\\w+) ?:表示只匹配但不获取匹配结果,为了优化;
[\\s\\S]*$ 表示结束可以是任意,包括什么都没有也行
【3】
[\\s\\S]+\\s+where\\s+[\\s\\S]+$
解释:
[\\s\\S]+\\s+where 表示只能是 任意字符(1到多次)+空白符(1到多次)+where,而如果是\\S+\\s+where 表示只能是 非空白符(1到多次)+空白符(1到多次)+where。
例如 a b where是不能被匹配到的。因为“ where”前面含有了空白符。
【4】
"abc|de|".replaceAll("(.*)\\|", "$1Java")
解释:
Java的replaceAll方法,以上执行结果将是:
abc|deJava
,即匹配最后一个“|”。
“\\|”表示为”|“这个特殊符号转义
“.*”表示任意字符可出现0次或多次,而*/+等默认都是贪婪模式,会尽可能多地匹配任意符号,故会将前一次的“|”也当做任意字符而不管,最后将只会匹配到“
abc|de|
”
而如果使用
"(.*?)\\|"
,?跟在限制符后面表示非贪婪模式,将会尽可能少的匹配任意字符,那么匹配结果将是:“
abc|
”和“
de|
”。
“
.*
”加括号
(.*)
表示设置分组,
如果替换、获取,可以用$1参数代替
“
.*
”匹配到的结果(即
abc|de
)。以下是几个replaceAll的例子,可以更好理解:
1.
"abc_d_d".replaceAll("_d","+Java")="ab+Java+Java"
因为_d匹配结果是_d和_d(两个),故将_d替换为+Java
2.
"abc_d_d".replaceAll(".*_d","+Java")="+Java"
因为.*_d匹配结果是abc_d_d,故将整个字符串替换为+Java
3.
"abc_d_d".replaceAll("(.*)_d","$1+Java")="abc_d+Java"
因为(.*)_d匹配结果是abc_d_d,故将整个字符串替换为$1+Java,而$1表示被括号包裹的内容(即abc_d),故替换后为abc_d+Java
4.
"abc_d_d".replaceAll(".*?_d","+Java")="+Java+Java"
因为.*?_d匹配结果是abc_d和_d,故将其均替换为+Java
5.
"abc_def_d".replaceAll("(.*?)_d","$1+Java")="abc+Javaef+Java"
因为(.*?)_d匹配结果是abc_d和ef_d,故均将其替换为$1+Java,而abc_d的$1表示被括号包裹的内容(即abc),故替换后为abc+Java,而ef_d的$1表示被括号包裹的内容(即为ef),故替换后为ef+Java
三、我常用的
1、JS 时间字符串转时间
var str="20170818102656";
str=str.replace(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/g,"$1/$2/$3 $4:$5:$6");
var date=new Date(str);
2、去掉循环累加的分割符的最后一个(如,)
String result="a,b,c,d,e,".replaceAll("^([\\s\\S]+),", "$1");
3、给形如xxx/cn/file.jpg 的url后缀名前加上时间,效果应为:xxx/cn/file20170506124530.jpg
String result = "xxx/cn/file.jpg".replaceAll("^([\\s\\S]+)(\\.\\w+)",$1" + DateTime.now().toString("yyyyMMddHHmmssSSS") + "$2");
//DateTime.now()位于joda包。
4、拦截一些SQL语句
Pattern.matches("^\\s*select[\\s\\S]*$", " select * from user") //true
Pattern.matches("^\\s*select\\s+count\\s*\\(\\s*(?:\\*|\\w+)\\s*\\)\\s+[\\s\\S]+$", " select count(*) from user") //true
"select * from user gourp by user.classid".matches("[\\s\\S]+\\s+gourp\\s+by\\s+[\\s\\S]+$") //true