记录Java基础-常用API-正则表达式与Lambda表达式的内容。
>正则表达式在线练习网站
java.util.regex
包中的Pattern
和Matcher
类实现。正则表达式长得像乱码例如:“[a-zA-Z0-9._%±]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$”
.
(点)匹配任意单个字符(除了换行符)。*
(星号)表示前面元素可以重复0次或多次。+
表示前面元素至少出现一次。?
表示前面元素可选,出现0次或1次。{m,n}
表示前面元素至少出现m次,至多n次。^
表示从字符串的头部开始匹配。$
表示从字符串的尾部开始匹配。a|b
表示匹配|前后任一字符。(a或b)a\b
转义字符,用于匹配一些保留的字符 `[ ] ( ) { } . * + ? ^ $(abc)
匹配括号中完全相等的字符。(与“abc”完全相同)常用[abc]
匹配方括号内的任一字符。("abc"中任一字符)常用[^abc]
匹配任何不在方括号内的字符。("abc"以外任一字符常用例'..o':
表示匹配前两位任意,以o结尾的字符串
比如“HelloWorld”中的`llo`。
例'abc[abc]':表示匹配‘abc+[含abc任一字符]'
比如'abca','abcb','abcc',注意只会匹配一个[]中的字符,匹配结果不会是'abcab','abcbc'之类
java.util.regex
包提供了多个类和方法来处理正则表达式。
compile(String regex)
:将给定的正则表达式字符串编译成一个Pattern对象。pattern()
:返回该Pattern对象所代表的正则表达式字符串。matcher(CharSequence input)
方法创建Matcher对象,用于在输入文本上执行匹配操作。matches()
:检查整个输入序列是否与该模式匹配。find()
:查找与该模式匹配的输入序列的下一个子序列。lookingAt()
:从输入开始判断是否有一个匹配此模式的前缀。group(int group)
:获取与指定组号匹配的子序列。replaceAll(String replacement)
:将所有与该模式匹配的子序列替换为另一个字符串。replaceFirst(String replacement)
:仅将第一个与该模式匹配的子序列替换为另一个字符串。String.matches(String regex)
:检查此字符串是否匹配给定的正则表达式。String.split(String regex)
:根据给定的正则表达式拆分此字符串,返回包含子串的数组。String.replaceAll(String regex, String replacement)
和 String.replaceFirst(String regex, String replacement)
类似于Matcher类中的替换方法。使用示例:
import java.util.regex.*;
public class RegexExample {
public static void main(String[] args) {
// 编译正则表达式
Pattern pattern = Pattern.compile("\\d{3}-\\d{2}-\\d{4}");
// 创建Matcher对象并提供待匹配文本
Matcher matcher = pattern.matcher("123-45-6789");
// 进行匹配操作
if (matcher.matches()) {
System.out.println("Match found!");
} else {
System.out.println("No match found.");
}
// 替换操作
String input = "My SSN is 123-45-6789";
String replaced = input.replaceAll("\\d{3}-\\d{2}-\\d{4}", "***-**-****");
System.out.println(replaced);
}
}
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class EmailValidator {
//用字符串常量声明正则表达式
private static final String EMAIL_PATTERN = "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$";
public static boolean isValidEmail(String email) {
//用Pattern.compile(EMAIL_PATTERN)方法,将这个正则表达式编译成一个Pattern对象
Pattern pattern = Pattern.compile(EMAIL_PATTERN);
//用macher方法校验正则表达式
Matcher matcher = pattern.matcher(email);
//结果为true/false
return matcher.matches();
}
public static void main(String[] args) {
String testEmail = "[email protected]";
if (isValidEmail(testEmail)) {
System.out.println("邮箱地址格式正确");
} else {
System.out.println("邮箱地址格式不正确");
}
}
}
^
表示匹配字符串的开始。[\\w-\\.]+
匹配一个或多个字母、数字、下划线、破折号或点字符,这里用来匹配邮箱名部分(如example
)。@
是邮箱地址中必不可少的符号。([\\w-]+\\.)+
匹配一个或多个由字母、数字、下划线或破折号组成的子串,后面跟着一个点字符,这里用来匹配域名的一部分(如example.com
中的example.
)。[\\w-]{2,4}
匹配两个到四个字母、数字、下划线或破折号,这里用来匹配顶级域名(如.com
、.net
等)。中国大陆手机号码的格式通常为:1开头,第二位到第三位可以是3-9之间的数字,接下来8位是任意数字。截至2024年,中国移动、中国联通、中国电信和中国广电四大运营商的号码段已经扩展,正则表达式可能需要包含这些最新的号段。
一个较为通用且能涵盖大部分情况的正则表达式如下:
^(1[3-9]\d{9})$
^
表示匹配字符串的开始。(1[3-9]\d{9})
匹配以1开头,第二位是3到9之间的数字,之后跟着8个任意数字(\d{9}
)。$
表示匹配字符串的结束。学习Lambda表达式前先了解匿名内部类
>点此查看和函数式接口
:
匿名内部类:
外部类
,实现重写外部类的方法,只在匿名内部类内部会生效。开发中一般不会这样使用。抽象类
,并必须实现里面所有抽象方法。接口
,并必须实现所有接口中所有抽象方法。//创建方式,new+类名()
new 外部类名() | 实现接口名() | 抽象类名(){
// 实现父类方法或接口方法
// 可以定义自己的成员变量和方法
};
//引用给对象
类名 对象名 = new 外部类名() | 实现接口名() | 抽象类名(){...}
Class c = new Class(){
public void run(){
}
};
c.run();
当匿名内部类
在只实现一个只需要实现单一方法的接口,即函数式接口
时,可以将其书写进一步精简,即为Lambda表达式
。
Lambda 表达式的书写规则:
Lambda 表达式的语法形式为:
(参数列表) -> { 函数体 }
其中,参数列表和函数体可以省略某些部分。
例如,以下是一个 Lambda 表达式示例:
(x, y) -> x + y
这个 Lambda 表达式表示一个简单的加法函数,接受两个参数 x 和 y,并返回它们的和。
Lambda 表达式也可以用于实现只有一个抽象方法的接口,例如:
interface MyInterface {
void myMethod();
}
MyInterface m = () -> System.out.println("Hello, world!");
m.myMethod(); // 输出 "Hello, world!"
在这个例子中,Lambda 表达式 () -> System.out.println(“Hello, world!”) 实现了 MyInterface 接口的 myMethod 方法。这个 Lambda 表达式没有参数,并执行了一个简单的打印操作。
Lambda 表达式必须是函数式接口的实现。函数式接口是指只有一个抽象方法的接口。如果接口有多个抽象方法,则无法使用 Lambda 表达式实现该接口。
Lambda 表达式的主体必须是一个表达式或一个代码块,不能是空的。也就是说,Lambda 表达式的主体必须有一个返回值或执行某些操作。
Lambda 表达式的参数列表必须与函数式接口的参数列表匹配。如果函数式接口有参数,则
Lambda 表达式不能嵌套在其他表达式中,它必须是语句的主体。也就是说,Lambda 表达式不能作为赋值语句、条件语句或循环语句的一部分。
Lambda 表达式不能被继承或被其他类实现。它只能被实现为函数式接口的具体实现类或对象。
Lambda 表达式不能直接访问其外部类的成员变量和方法,除非这些成员被声明为 final 或通过 this 关键字引用。这是因为 Lambda 表达式实际上是一个独立的类,它不能访问其外部类的非静态成员。
如果 Lambda 表达式的主体只有一个语句,且该语句是一个返回语句,则可以省略大括号和 return 关键字。例如,以下两种写法是等价的:
x -> x * x
x -> { return x * x; }
Lambda 表达式的参数列表和函数体可以省略某些部分,但它们之间必须使用箭头符号 -> 分隔开。例如,以下写法是合法的:
x -> x * x(省略了参数列表和函数体)
(x, y) -> x + y(省略了函数体)
(int x) -> x * x(指定了参数类型)
(int x, int y) -> { return x * y; }(指定了参数类型和函数体)
Lambda 表达式的参数列表可以使用默认值,但函数体不能使用默认值。这是因为默认值是用于简化代码的,而不是用于表示函数体的逻辑。例如,以下写法是合法的:
(x, y = 10) -> x + y(y 有默认值)
(x, y) -> x + y(没有默认值)
Lambda 表达式可以用于方法参数、回调函数、Map 的键值等场合,但不能用于变量声明、方法返回值、数组初始化等场合。这是因为 Lambda 表达式本身是一个表达式而不是一个对象或变量。