先来个例子
public static final Pattern CHINESE_PATTERN = Pattern.compile("[\\u4e00-\\u9fa5]");
/ 检测字符串是否包含汉字
String text = "Hello 世界";
boolean hasChinese = CHINESE_PATTERN.matcher(text).find(); // 返回 true// 提取所有汉字
Matcher matcher = CHINESE_PATTERN.matcher(text);
while (matcher.find()) {System.out.println(matcher.group()); // 输出 "世" 和 "界"
}// 移除非汉字字符
String chineseOnly = text.replaceAll(CHINESE_PATTERN.pattern(), "");
// 结果为 "世界"
1. 核心步骤
-
编译正则表达式:通过
Pattern.compile()
将字符串形式的正则表达式编译为Pattern
对象。 -
创建Matcher对象:通过
Pattern.matcher(CharSequence input)
生成Matcher
实例。 -
执行匹配操作:使用
Matcher
的方法进行匹配、查找、替换等操作。
2. 基础用法示例
匹配整个字符串
Pattern pattern = Pattern.compile("\\d+"); // 匹配一个或多个数字
Matcher matcher = pattern.matcher("1234");
boolean isMatch = matcher.matches(); // true
查找子串
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("test 123 test 456");
while (matcher.find()) {System.out.println(matcher.group()); // 输出 123 和 456
}
替换操作
Matcher matcher = pattern.matcher("test 123 test 456");
String replaced = matcher.replaceAll("XXX"); // "test XXX test XXX"
3. 分组与捕获
正则表达式中的括号()
表示分组,可通过group(int group)
获取内容:
Pattern pattern = Pattern.compile("(\\w+)=(\\d+)"); // 键值对格式
Matcher matcher = pattern.matcher("key=123");
if (matcher.matches()) {String key = matcher.group(1); // "key"String value = matcher.group(2); // "123"
}
4. 常用方法
Matcher类
-
matches()
:整个字符串是否完全匹配。 -
find()
:查找下一个匹配的子串。 -
group()
:返回匹配的字符串(group(0)
等效)。 -
start()
/end()
:匹配子串的起始/结束索引。 -
replaceAll(String replacement)
:替换所有匹配项。 -
replaceFirst(String replacement)
:替换第一个匹配项。
Pattern类
-
split(CharSequence input)
:按正则式分割字符串。 -
static boolean matches(String regex, CharSequence input)
:快速匹配。
5. 示例代码
分割字符串
Pattern pattern = Pattern.compile(",");
String[] parts = pattern.split("a,b,c"); // ["a", "b", "c"]
命名分组(Java 7+)
Pattern pattern = Pattern.compile("(?<name>\\w+)=(?<value>\\d+)");
Matcher matcher = pattern.matcher("user=42");
if (matcher.find()) {String name = matcher.group("name"); // "user"String value = matcher.group("value"); // "42"
}
6. 注意事项
-
转义字符:Java字符串中的反斜杠需写为
\\
(如\\d
表示数字)。 -
异常处理:
Pattern.compile()
可能抛出PatternSyntaxException
。 -
状态依赖:调用
group()
前需先执行匹配操作(如find()
或matches()
)。
通过结合Pattern
和Matcher
,可以高效实现复杂的字符串匹配、提取和替换逻辑。
一、Java正则表达式特点
在程序开发过程中,经常回遇到需要匹配,查找,替换判断的情况,如果仅仅用纯编码的方式解决,肯定会很吃力,所以,正则表达式就出现了,目的就是用来处理字符串的一系列操作。
- 正则表达式定义了字符串的模式
- 正则表达式还支持多种语言,该文章用Java进行讲解。
二、基本语法
- 正则表达式最常用包为: java.util.regex,该包包括以下三个类(具体方法,参照java-API)
Pattern类:pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher类:Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException类:是一个非强制异常类,它表示一个正则表达式模式中的语法错误
- 基本规则:正则表达式大全语法:点这里
三、三大算法
3.1 搜索算法
- 作用:提供了有用的索引值,精确表明主串在哪能找到匹配(主串为被匹配的字符串,通常为输入或者某处获取的字符串,模式串为正则表达式锁表示的串)
- 主要使用的方法:
public int start():返回以前匹配的初始索引。
public int start(int group):返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
public int end():返回最后匹配字符之后的偏移量。
public int end(int group):返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。
public class Demo {public static final String TEST = "This is " +"my small example string which I'm going to use for pattern matching.";public static void main(String[] args) {Pattern pattern = Pattern.compile("(is)"); //含有单词is的位置Matcher matcher = pattern.matcher(TEST);System.out.println(TEST.length());// 检查所有的结果while (matcher.find()) { //find()返回Boolean类型,表示是否到字符串尾部,没有则后移System.out.println("Start index: " + matcher.start()); //起始位置System.out.println(" End index: " + matcher.end() + " "); //终点位置System.out.println(matcher.group()); //打印该组的信息}}
}
3.2 匹配算法
- 用于检查主字串是否符合模式串(返回值为Boolean类型)
- 主要使用的方法有:
public boolean lookingAt(): 尝试将从区域开头开始的输入序列与该模式匹配。 只要主串的开头匹配就可以返回true. 例如:abc去匹配abcde,开头匹配,则返回true。
public boolean find():尝试查找与该模式匹配的输入序列的下一个子序列。
public boolean find(int start):重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。
public boolean matches(): 尝试将整个区域与模式匹配。必须整个主串匹配才返回true
public class Demo {public static void main(String[] args) {String tel = "18000001111";String telReg = "1[358]\\d{9}"; // 字符串要匹配的正则表达式System.out.println(tel.matches(telReg));/*Pattern pattern = Pattern.compile("(15)|(18)|(13)");Matcher matcher = pattern.matcher("18000001111");System.out.println(matcher.lookingAt()); //表示只要以15/18/13开头即可,不需要满足11位数字*/Pattern pattern = Pattern.compile("1[358]\\d{9}");Matcher matcher = pattern.matcher("18000001111");System.out.println(matcher.matches()); //满足整个表达式的条件才返回true}
}
3.替换算法
- 替换方法是替换输入字符串里文本的方法。
- 主要方法有:
public String replaceAll(String replacement):替换模式串与给定替换字符串相匹配的所有字串(子序列)。
public String replaceFirst(String replacement):替换模式与给定替换字符串匹配的输入序列的第一个字串。
public Matcher appendReplacement(StringBuffer sb, String replacement): 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个 StringBuffer 对象里
public StringBuffer appendTail(StringBuffer sb):将最后一次匹配工作后剩余的字符串添加到一个 StringBuffer 对象里。
public static String quoteReplacement(String s):返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement 方法一个字面字符串一样工作。
public class Demo {public static void main(String[] args) {Pattern pattern = Pattern.compile("[a-zA-Z]");//匹配字符串中的英文字母String str1 = "erkktyqqquizzzzzo";//将叠词替换成$. //将重叠的字符替换成单个字母。zzzz->z// replaceAllDemo(str1,"(.)\\1+","$1");Matcher matcher = pattern.matcher("wer1389980000ty1234564uiod234345675f");System.out.println(matcher.replaceAll("#")); //将所有英文字母替换为#System.out.println(matcher.replaceFirst("\\¥")); //将第一个英文字母替换为¥}
}
此外,对于 appendReplacement 与 appendTail的操作如下:
public class Demo {//为了方便以及维护,通常将主串写为静态私有的全员变量private static String REGEX = "a*b";private static String INPUT = "aabfooaabfooabfoobkkk";private static String REPLACE = "-";public static void main(String[] args) {Pattern pattern = Pattern.compile(REGEX);Matcher matcher = pattern.matcher(INPUT);StringBuffer sb = new StringBuffer();while (matcher.find()) {matcher.appendReplacement(sb, REPLACE); //将所有已替换的字串 和 该字串后的字串保存道sb对象中去}System.out.println(sb);matcher.appendTail(sb); //将最后一个可替换字串之后的字串保存到对象中去 即将kkk保存到sb对象中//System.out.println(sb.toString());System.out.println(sb);//对象自动调用了toString方法}
}