一、正则表达式
一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配 "Hello World" 字符串。
.(点号)也是一个正则表达式,它匹配任何一个字符如:"a" 或 "1"。
下表列出了一些正则表达式的实例及描述:
正则表达式 | 描述 |
---|---|
this is text | 匹配字符串 "this is text" |
this\s+is\s+text | 注意字符串中的 \s+。 匹配单词 "this" 后面的 \s+ 可以匹配多个空格,之后匹配 is 字符串,再之后 \s+ 匹配多个空格然后再跟上 text 字符串。 可以匹配这个实例:this is text |
^\d+(\.\d+)? | ^ 定义了以什么开始 \d+ 匹配一个或多个数字 ? 设置括号内的选项是可选的 \. 匹配 "." 可以匹配的实例:"5", "1.5" 和 "2.21"。 |
java正则表达式的包:java.util.regex ,主要有三个类:
1、Pattern 类,pattern 对象是一个正则表达式的编译表示
2、Matcher 类,Matcher 对象是对输入字符串进行解释和匹配操作的引擎
3、PatternSyntaxException,PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误
示例:
package com.zhouzy.base.t6;
import java.util.regex.Pattern;
import org.junit.Test;
public class RegexTest {
/**
* 1. 任意一个字符表示匹配任意对应的字符,如a匹配a,7匹配7,-匹配-。
2. []代表匹配中括号中其中任一个字符,如[abc]匹配a或b或c。
3. -在中括号里面和外面代表含义不同,如在外时,就匹配-,如果在中括号内[a-b]表示匹配26个小写字母中的任一个;[a-zA-Z]匹配大小写共52个字母中任一个;[0-9]匹配十个数字中任一个。
4. ^在中括号里面和外面含义不同,如在外时,就表示开头,如^7[0-9]表示匹配开头是7的,且第二位是任一数字的字符串;如果在中括号里面,表示除了这个字符之外的任意字符(包括数字,特殊字符),如[^abc]表示匹配出去abc之外的其他任一字符。
5. .表示匹配任意的字符。
6. \d表示数字。
7. \D表示非数字。
8. \s表示由空字符组成,[ \t\n\r\x\f]。
9. \S表示由非空字符组成,[^\s]。
10. \w表示字母、数字、下划线,[a-zA-Z0-9_]。
11. \W表示不是由字母、数字、下划线组成。
12. ?: 表示出现0次或1次。
13. +表示出现1次或多次。
14. *表示出现0次、1次或多次。
15. {n}表示出现n次。
16. {n,m}表示出现n~m次。
17. {n,}表示出现n次或n次以上。
18. XY表示X后面跟着Y,这里X和Y分别是正则表达式的一部分。
19. X|Y表示X或Y,比如"food|f"匹配的是foo(d或f),而"(food)|f"匹配的是food或f。
20. (X)子表达式,将X看做是一个整体。
*/
//手机号的正则表达式^表示开始,$表示结束
String phoneRegex = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";;
//邮箱的正则表达式
String emailRegex = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
//身份证正则表达式
String personCardRegex = "(^\\d{18}$)|(^\\d{15}$)";
//URL正则表达式
String urlRegex = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
@Test
public void regexTest(){
System.out.println("10086-isPhone:"+isPhone("10086"));
System.out.println("test@163.com-isEmail:"+isEmail("test@163.com"));
System.out.println("430624198808218123-isPersonCard:"+isPersonCard("430624198808218123"));
System.out.println("https://baidu.com-isUrl:"+isUrl("https://baidu.com"));
}
/**
* 判断是否是手机号
* @param phone
* @return
*/
private boolean isPhone(String phone){
return Pattern.matches(phoneRegex, phone);
}
/* 判断是否是邮箱
* @param email
* @return
*/
private boolean isEmail(String email){
return Pattern.matches(emailRegex, email);
}
/* 判断是否是身份证
* @param personCard
* @return
*/
private boolean isPersonCard(String personCard){
return Pattern.matches(personCardRegex, personCard);
}
/* 判断是否是身份证
* @param personCard
* @return
*/
private boolean isUrl(String url){
return Pattern.matches(urlRegex, url);
}
}
结果:
10086-isPhone:false
test@163.com-isEmail:true
430624198808218123-isPersonCard:true
https://baidu.com-isUrl:true
matcher类示例
@Test
public void matcherTest(){
String urlRegex = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
String url1 = "aabb";
String url2 = "https://hao123.com https://baidu.com";
Pattern p = Pattern.compile(urlRegex);
Matcher m1 = p.matcher(url1); // 获取 matcher 对象
Matcher m2 = p.matcher(url2); // 获取 matcher 对象
int count1 = 0;
while(m1.find()) {
count1++;
System.out.println("m1:Match number "+count1);
System.out.println("m1:start(): "+m1.start());
System.out.println("m1:end(): "+m1.end());
}
int count2 = 0;
while(m2.find()) {
count2++;
System.out.println("m2:Match number "+count2);
System.out.println("m2:start(): "+m2.start());
System.out.println("m2:end(): "+m2.end());
}
}
结果:
m2:Match number 1
m2:start(): 0
m2:end(): 18
m2:Match number 2
m2:start(): 19
m2:end(): 36
二、方法
1、定义
其实前面已经见过方法了,Java方法是语句的集合,它们在一起执行一个功能。
1)方法是解决一类问题的步骤的有序组合
2)有利于程序维护
3)可以提高程序开发的效率
4)提高了代码的重用性
语法:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
比如前面一个简单的方法:
/**
* 判断是否是手机号
* @param phone
* @return
*/
private boolean isPhone(String phone){
return Pattern.matches(phoneRegex, phone);
}
上面是有返回值的,返回值是boolean类型,如果不想用返回值,则用void替代,比如
public void regexTest(){
System.out.println("10086-isPhone:"+isPhone("10086"));
System.out.println("test@163.com-isEmail:"+isEmail("test@163.com"));
System.out.println("430624198808218123-isPersonCard:"+isPersonCard("430624198808218123"));
System.out.println("https://baidu.com-isUrl:"+isUrl("https://baidu.com"));
}
2、方法的重载
方法重载是指在同一个类中方法名字相同,返回值或参数不相同,比如:
/**
* 判断是否是手机号
* @param phone
* @return
*/
private boolean isPhone(String phone){
return Pattern.matches(phoneRegex, phone);
}
public void isPhone(String phone1,String phone2){
boolean b = Pattern.matches(phoneRegex, phone1) && Pattern.matches(phoneRegex, phone2);
System.out.println(b);
}
3、变量作用域
变量的范围是程序中该变量可以被引用的部分。
方法内定义的变量被称为局部变量。
局部变量的作用范围从声明开始,直到包含它的块结束。
局部变量必须声明才可以使用。
方法的参数范围涵盖整个方法。参数实际上是一个局部变量。
for循环的初始化部分声明的变量,其作用范围在整个循环。
但循环体内声明的变量其适用范围是从它声明到循环体结束。它包含如下所示的变量声明:
4、可变参数
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
方法的可变参数的声明如下所示:
typeName... parameterName
@Test
public void phoneTest(){
isPhone("13349668342","10086","100865");
}
public void isPhone(String... phones){
if(phones.length > 0){
for(String phone : phones){
boolean b = Pattern.matches(phoneRegex, phone);
System.out.println(phone+":"+b);
}
}
}
结果:
13349668342:true
10086:false
100865:false
5、finalize() 方法
Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。
三、异常
1、定义
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
1)检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
2)运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略
3)错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的
所有的异常类是从 java.lang.Exception 类继承的子类
常见的异常:
2、捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方
语法:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}
示例:
@Test
public void getDiffDays() {
try {
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
Date d1 = ft.parse("2021-07-12 21:32:43");
Date d2 = ft.parse("aaaa");
Long l1 = d1.getTime();
Long l2 = d2.getTime();
Long diffMill = l2 - l1;
Long diffDays = diffMill/(60*60*24*1000);
System.out.println("格式化后时间为d1:" + ft.format(d1)+",d2:"+ft.format(d2)+",相差天数:"+diffDays);
} catch (ParseException e) {
e.printStackTrace();
}
}
结果:
3、throws/throw 关键字
@Test
public void exceptionTest() throws Exception{
File f = new File("E://test.txt");
if(!f.exists()){
//f.createNewFile();
throw new Exception();
}
}
4、finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
@Test
public void finallyTest() {
try {
int a = 0;
int b = 2;
System.out.println(b/a);
} catch (Exception e) {
e.printStackTrace();
}finally{
System.out.println("最终还是执行了我");
}
}
结果:
5、自定义异常
编写自己的异常类时需要记住下面的几点
1)所有异常都必须是 Throwable 的子类
2)如果希望写一个检查性异常类,则需要继承 Exception 类
3)如果你想写一个运行时异常类,那么需要继承 RuntimeException 类
自定义异常:
package com.zhouzy.base.t6;
public class MyException extends Exception{
/**
*
*/
private static final long serialVersionUID = 7710033563229732580L;
public MyException(){
super();
}
public MyException(String message){
super(message);
}
public MyException(String message,Throwable cause){
super(message,cause);
}
}
使用自定义异常:
@Test
public void myExceptionTest() throws Exception{
int a = 0;
if(a == 0){
throw new MyException("a==0,异常");
}
}
结果:
四、Scanner 类
java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。
下面是创建 Scanner 对象的基本语法:
Scanner s = new Scanner(System.in);
示例:
@Test
public void scannerTest(){
Scanner s = new Scanner(System.in);
// 从键盘接收数据
// 判断是否还有输入
while (s.hasNext()) {
String ss = s.next();
System.out.println("输入的数据为:" + ss);
if("exit".equals(ss)){
s.close();
}
}
}
结果:
a
输入的数据为:ab
输入的数据为:bssss
输入的数据为:ssssexit
输入的数据为:exit