记录Java基础-常用API-正则表达式与Lambda表达式的内容。
1 正则表达式详解
>正则表达式在线练习网站
- 正则表达式是一种强大的文本处理工具,它使用特殊的字符和模式来匹配、查找、替换或提取字符串中的特定内容。
- 在Java中,正则表达式的功能主要通过
java.util.regex
包中的Pattern
和Matcher
类实现。
正则表达式长得像乱码例如:“[a-zA-Z0-9._%±]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$”
1.1 正则表达式的作用
- 简化编程:使用正则表达式可以避免编写大量针对字符串处理的循环和条件判断代码,极大地简化了文本搜索、替换、分割等操作。
- 验证输入格式:例如检查电子邮件地址、URL、电话号码、日期等是否符合预定义的格式规范。
- 搜索和替换:在文本中查找特定模式的所有出现,并进行替换操作。
- 数据提取:从大量文本中抽取出满足某种模式的信息片段。
- 文本分割:按照特定分隔符将一个长字符串拆分为多个子串
1.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'之类
1.3 类方法
java.util.regex
包提供了多个类和方法来处理正则表达式。
1.3.1 Pattern类:
-
compile(String regex)
:将给定的正则表达式字符串编译成一个Pattern对象。 -
pattern()
:返回该Pattern对象所代表的正则表达式字符串。
1.3.2 Matcher类:
- 通过Pattern类的
matcher(CharSequence input)
方法创建Matcher对象,用于在输入文本上执行匹配操作。 -
matches()
:检查整个输入序列是否与该模式匹配。 -
find()
:查找与该模式匹配的输入序列的下一个子序列。 -
lookingAt()
:从输入开始判断是否有一个匹配此模式的前缀。 -
group(int group)
:获取与指定组号匹配的子序列。 -
replaceAll(String replacement)
:将所有与该模式匹配的子序列替换为另一个字符串。 -
replaceFirst(String replacement)
:仅将第一个与该模式匹配的子序列替换为另一个字符串。
1.3.3 其他相关方法:
- String类中的方法也支持正则表达式操作:
-
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);
}
}
1.4 正则表达式案例
1.4.1 注册页面验证邮箱格式
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 = "example@example.com";
if (isValidEmail(testEmail)) {
System.out.println("邮箱地址格式正确");
} else {
System.out.println("邮箱地址格式不正确");
}
}
}
-
^
表示匹配字符串的开始。 -
[\\w-\\.]+
匹配一个或多个字母、数字、下划线、破折号或点字符,这里用来匹配邮箱名部分(如example
)。 -
@
是邮箱地址中必不可少的符号。 -
([\\w-]+\\.)+
匹配一个或多个由字母、数字、下划线或破折号组成的子串,后面跟着一个点字符,这里用来匹配域名的一部分(如example.com
中的example.
)。 -
[\\w-]{2,4}
匹配两个到四个字母、数字、下划线或破折号,这里用来匹配顶级域名(如.com
、.net
等)。
1.4.2 注册页面验证手机号格式
中国大陆手机号码的格式通常为:1开头,第二位到第三位可以是3-9之间的数字,接下来8位是任意数字。截至2024年,中国移动、中国联通、中国电信和中国广电四大运营商的号码段已经扩展,正则表达式可能需要包含这些最新的号段。
一个较为通用且能涵盖大部分情况的正则表达式如下:
^(1[3-9]\d{9})$
-
^
表示匹配字符串的开始。 -
(1[3-9]\d{9})
匹配以1开头,第二位是3到9之间的数字,之后跟着8个任意数字(\d{9}
)。 -
$
表示匹配字符串的结束。
2 Lambda表达式详解
学习Lambda表达式前先了解匿名内部类
>点此查看和函数式接口
:
-
匿名内部类:
- 在java类中只使用一次且不需要单独定义一个类的情况下,可以声明一个匿名内部类来简化代码。
- 匿名内部类声明时即实例化为一个对象,类型为当前new的那个类的子类。
- 匿名内部类可以继承非静态(static)的
外部类
,实现重写外部类的方法,只在匿名内部类内部会生效。开发中一般不会这样使用。 - 匿名内部类可以继承
抽象类
,并必须实现里面所有抽象方法。 - 匿名内部类可以实现一个或多个
接口
,并必须实现所有接口中所有抽象方法。
//创建方式,new+类名()
new 外部类名() | 实现接口名() | 抽象类名(){
// 实现父类方法或接口方法
// 可以定义自己的成员变量和方法
};
//引用给对象
类名 对象名 = new 外部类名() | 实现接口名() | 抽象类名(){...}
Class c = new Class(){
public void run(){
}
};
c.run();
-
函数式接口:
- 只有一个抽象方法的接口。这个接口可以包含其他的方法(如静态方法、默认方法或私有方法)。
当匿名内部类
在只实现一个只需要实现单一方法的接口,即函数式接口
时,可以将其书写进一步精简,即为Lambda表达式
。
2.1 什么是Lambda表达式?
- Lambda表达式是Java 8 引入的一个新特性,用于简化函数式接口的一种语法糖(语法糖,表示编程中更简洁的语法结构)。
- 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 表达式不能被继承或被其他类实现。它只能被实现为函数式接口的具体实现类或对象。
-
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 表达式的参数列表可以使用默认值,但函数体不能使用默认值。这是因为默认值是用于简化代码的,而不是用于表示函数体的逻辑。例如,以下写法是合法的:文章来源:https://www.toymoban.com/news/detail-805111.html
(x, y = 10) -> x + y(y 有默认值)
(x, y) -> x + y(没有默认值)
Lambda 表达式可以用于方法参数、回调函数、Map 的键值等场合,但不能用于变量声明、方法返回值、数组初始化等场合。这是因为 Lambda 表达式本身是一个表达式而不是一个对象或变量。文章来源地址https://www.toymoban.com/news/detail-805111.html
到了这里,关于【自学笔记】01Java基础-08Java常用API:05正则表达式与Lambda表达式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!