/*
* 需求:校验qq号
* 要求:长度5-15;只能是数字;0不能开头
*/
public static void checkQQ(String qq){
int length=qq.length();
if(length>=5&&length<=15){
if (!qq.startsWith("0")) {
try {
Long l=Long.parseLong(qq);
System.out.println("正确!");
} catch (NumberFormatException e) {
System.out.println(qq+":不是数字错误!");
}
}else {
System.out.println(qq+":0开头错误!");
}
}else {
System.out.println(qq+":长度错误!");
}
}
在正则表达式面前,它显然有些麻烦,但是它还是有优点就是易读,很容易看懂代码意思。
使用正则表达式,代码就变成了
public static void checkQQByRegex(String qq){
String regex="[1-9][0-9]{4,14}";
boolean b=qq.matches(regex);
System.out.println(qq+":"+b);
}
简单的正则表达式,却不容易读懂,因此我们需要记很多符号代表的意思。
二、一些常用需要记忆的符号
字符类 | |
---|---|
[abc] | a、b 或 c(简单类) |
[^abc] | 任何字符,除了 a、b 或c(否定) |
[a-zA-Z] | a 到 z 或 A 到 Z,两头的字母包括在内(范围) |
[a-d[m-p]] | a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z&&[def]] | d、e 或 f(交集) |
[a-z&&[^bc]] | a 到 z,除了 b 和 c:[ad-z](减去) |
[a-z&&[^m-p]] | a 到 z,而非 m 到 p:[a-lq-z](减去) |
预定义字符类 | |
---|---|
. | 任何字符(与行结束符可能匹配也可能不匹配) |
\d | 数字:[0-9] |
\D | 非数字: [^0-9] |
\s | 空白字符:[ \t\n\x0B\f\r] |
\S | 非空白字符:[^\s] |
\w | 单词字符:[a-zA-Z_0-9] |
\W | 非单词字符:[^\w] |
边界匹配器 | |
---|---|
^ | 行的开头 |
$ | 行的结尾 |
\b | 单词边界 |
\B | 非单词边界 |
\A | 输入的开头 |
\G | 上一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
\z | 输入的结尾 |
Greedy 数量词 | |
---|---|
X? | X,一次或一次也没有 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X{n} | X,恰好 n 次 |
X{n,} | X,至少 n 次 |
X{n,m} | X,至少 n 次,但是不超过m 次 |
三、常用功能
1、匹配:其实就是String类中matches方法
/*
* 匹配功能
* 需求:校验手机号
* 要求:11位,开头13、15、18
*/
public static void fun1() {
String phone="13511110000";
String regex="1[358]\\d{9}";//等同于String regex="1[358][0-9]{9}"
boolean b=phone.matches(regex);
System.out.println(phone+":"+b);
}
2、替换:其实就是String类中replaceAll方法,不是replace方法
/*
* 替换功能
* 需求:将已知电话号码,替换成形如152****0000
*/
public static void fun3() {
String phone="15200001111";
String newPhone=phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");//$1取前一个表达式中第一组
System.out.println(newPhone);
}
3、切割:其实就是String类中split方法
/*
* 切割功能
* 需求:从字符串叠词部分切割
*/
public static void fun2() {
String s="张三@@@李四aaa王五";
String regex="(.)\\1+";//.任意字符,()组,\1取第一组,+至少出现一次
String strs[]=s.split(regex);
for (String string : strs) {
System.out.println(string);
}
}
4、获取:为了String类方便提供了上面方法,其实底层都是使用了Pattern类
/*
* 获取功能
* 需求:获取“da jia hao,wo shi zhang san!”中三个字母组成的字符串
*/
public static void fun4() {
String s="da jia hao,wo shi zhang san!";
String regex="\\b[a-z]{3}\\b";//单词边界\b
Pattern p=Pattern.compile(regex);//将正则封装成对象
Matcher m=p.matcher(s);//绑定字符串获取匹配器
//使用匹配器的find方法
while (m.find()) {//find 方法扫描输入序列以查找与该模式匹配的下一个子序列。
System.out.println(m.group());//返回由以前匹配操作所匹配的输入子序列。
}
}
四、练习
1、治口吃
/*
* 需求:治口吃
*/
public static void kouchi() {
String s="我我我我....要要要要要要...学学..加..瓦!";
//第一步替换...
String s2=s.replaceAll("\\.+", "");
//第二部替换叠词
String s3=s2.replaceAll("(.)\\1+", "$1");
System.out.println(s3);
}
2、对ip地址排序
/*
* 需求:对ip地址进行排序
*/
public static void ipSort() {
String s="192.168.0.1 127.0.0.1 133.1.1.1 88.0.192.1";
Set<String> set=new TreeSet<String>();//使用treeset排序的功能
//截取字符串,放入set中,因为字符长度不同,所以排序失败,所以需要补0
s=s.replaceAll("(\\d+)", "00$1");//00127.000.000.001
//保留3位数
s=s.replaceAll("\\d+(\\d{3})", "$1");//088.000.192.001
String strs[]=s.split(" +");
for (String string : strs) {
set.add(string);
}
for (String str : set) {
//去除0打头和两位0
str=str.replaceAll("0{1,2}(\\d+)", "$1");
System.out.println(str);
}
}
3、对邮箱进行校验
/*
* 邮箱地址校验
*/
public static void checkMail() {
String mail="zhangsan@sina.com.cn";
String regex="\\w+@\\w+(\\.\\w+)+";
boolean b=mail.matches(regex);
System.out.println(mail+":"+b);
}
4、网页爬虫获取邮箱
/*
* 网页爬虫获取邮箱
*/
public static List<String> getMail(String addr) throws Exception {
URL url=new URL(addr);
BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream()));//获取输入流
Pattern p=Pattern.compile("\\w+@\\w+(\\.\\w+)+");//封装
Matcher m=null;
String s=null;
List<String> mails=new ArrayList<String>();
while ((s=br.readLine())!=null) {
m=p.matcher(s);//绑定字符串
while (m.find()) {
mails.add(m.group());
}
}
return mails;
}