本来以为正则表达式很简单的,不就是匹配一个字符串吗,今天仔细看了书,发现好多地方自己都不懂,上网找了找资料,发现正则表达式还是很强大的,而且想完全理解还是有一定难度的。
ps:在网上找资料的过程中,发现很多人写的有错误,而且错的都一样,不过我自己把代码敲了一边,让编译器去判断就知道错误了。
这点我想告诉初学者,不要相信书上的就是对的,一定要自己敲一遍,编译通过了的才是正确的,有时看到两篇讲的矛盾的代码时,一定要都将它们在编译器里面编译一遍,这样就很容易知道谁对谁错了!
我们先来讲一个例子吧,我们写一个验证邮箱格式是否正确的代码。
import java.util.regex.Pattern;
import java.util.*;
public class Regular_expression
{
public static void main(String[] args)
{
Pattern pattern=Pattern.compile("^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)+$;);//正则表达式
Scanner input1=new Scanner(System.in);
System.out.println("请输入要匹配的邮箱:");
String patternString=input1.nextLine();
boolean result=pattern.matcher(patternString).matches();
if(result)
System.out.println("匹配成功!");
else
System.out.println("匹配失败!");
}
}
上面的正则表达式是:^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)+$
下面我就来说说为什么上面的正则表达式就可以判断一个邮箱的格式是否正确。
1.[]
匹配方括号里面列出的一个字符,注意,只代表一个字符,例如A[DN]D只能匹配ADD,和AND,上例中[_a-z0-9-]表示匹配‘_’,a-z中的一个字母,0-9中的某个数字或者‘-’,注意,如果你想匹配0或9或者-,请不要写成[0-9],这样会被编译器认为是0到9中的一个数,可以写成这样[09-];
2.^和$
^和$分别匹配开头和结尾,上例中^[_a-z0-9-]的意思就是开头只能是中括号中列出的这些字符,而(\\.[a-z0-9-]+)+$表示结尾只能是前面一个组所匹配的字符。
注意:当^在中括号里面的时候,他的含义就是排除该字符的意思,例如[^a][abc]就是可以匹配所有第一个字符不以‘a’开头,第二个字符可以是‘a’,‘b’,‘c’中任一个的字符串,这里我想纠正本人看的一本书中的错误,《java开发入行真功夫》中他只介绍了^作为否定次的功能,而没有讲清其主要是匹配开头字符的。
正则表达式还有很多匹配开头结尾的特殊字符,下面列出一些:
\b 单词边界 相当于^[a-zA-Z]
\B 非单词边界 相当于[^a-zA-Z]
3.表示匹配次数的符号
符号 | 匹配次数 |
* | 0次或者多次 |
+ | 1次或者多次 |
? | 0次或者1次 |
{n} | 只能n次 |
{n,m} | 从n次到m次之间 |
上例中(\\.[_a-z0-9-]+)*也表示匹配有0个或者多个前面所匹配的字符。
4.\转义符号
java中定义了一些特殊的字符用来快捷处理
快捷字符 | 等价的正则表达式 | 含义 |
\d | [0-9] | 数字 |
\D | [^0-9] | 非数字 |
\w | [a-zA-Z0-9_] | 单词字符 |
\W | [^a-zA-Z0-9_] | 非单词字符 |
\s | [ \t\n\f\r] | 空格字符(空格,制表,换行,回车,换页) |
\S | [^\s] | 非空格字符 |
上表要注意两点l:
一是\w 表示单词字符,包含下划线‘_’,我在网上看到很多人都把下划线漏掉了,而且\s包含空格
因为java中有了这些以\开头的特殊字符,所以我们表示一些字符时就可能有点困难,这个地方也是我今天搞了很久才明白的问题
这样我们在想表达\d正则表达式时就要写成\\d,
想匹配一个\时就要写成\\\\(仔细想象,可以想明白的)
想匹配一个*,+,?时就要写成\\*,\\+,\\?
这个地方要好好搞清楚,一般的正则表达式中肯定有大量的转义字符
5.点号(.)和或(|)
这两个都是上例中没有用到的符号。
点号:. 相当于一个通配符,可以匹配所有字符 例如A.D可以匹配ADD,AID,AnD等等类似字符
这时,大家再回头看例子中的正则表达式应该很好理解了吧。
下面附上我在网上找的别人写的一些具体功能的正则表达式,大家可以参考,不过建议大家自己检验一下,以防出现错误
"^\d+$" //非负整数(正整数 + 0)
"^[0-9]*[1-9][0-9]*$" //正整数
"^((-\d+)|(0+))$" //非正整数(负整数 + 0)
"^-[0-9]*[1-9][0-9]*$" //负整数
"^-?\d+$" //整数
"^\d+(\.\d+)?$" //非负浮点数(正浮点数 + 0)
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$" //正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$" //非正浮点数(负浮点数 + 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负浮点数
"^(-?\d+)(\.\d+)?$" //浮点数
"^[A-Za-z]+$" //由26个英文字母组成的字符串
"^[A-Z]+$" //由26个英文字母的大写组成的字符串
"^[a-z]+$" //由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$" //由数字和26个英文字母组成的字符串
"^\w+$" //由数字、26个英文字母或者下划线组成的字符串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" //email地址
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$" //url
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/ // 年-月-日
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/ // 月/日/年
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$" //Emil
"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?" //电话号码
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$" //IP地址
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空行的正则表达式:\n[\s| ]*\r
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/
匹配首尾空格的正则表达式:(^\s*)|(\s*$)
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址URL的正则表达式:^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配国内电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
正确格式为:“XXXX-XXXXXXX”,“XXXX-XXXXXXXX”,“XXX-XXXXXXX”,
“XXX-XXXXXXXX”,“XXXXXXX”,“XXXXXXXX”。
验证身份证号(15位或18位数字):“^d{15}|d{}18$”
匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$
匹配中文字符的正则表达式: [u4e00-u9fa5]
匹配双字节字符(包括汉字在内):[^x00-xff]
应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
String.prototype.len=function(){return this.replace([^x00-xff]/g,"aa").length;}
匹配空行的正则表达式:n[s| ]*r
匹配HTML标记的正则表达式:/<(.*)>.*</1>|<(.*) />/
匹配首尾空格的正则表达式:(^s*)|(s*$)