在学习java正则表达式时,遇到三个问题。
1、java字符串和正则模式的字符串很不清楚
2、正则中有捕获组的概念,并且还能对捕获后的组进行字符串替换,即appendReplacement(StringBuffer sb, String replacement)方法的原理不清楚
3、为什么在调用appendReplacement(StringBuffer sb, String replacement)方法之前需要对replacement中的"\"和"$"字符进行转义。
java正则表达式一般是对于字符串的操作,个人理解在正则表达式中,字符串有三个基本的概念:
第一,代码字符串:写在java文件中的字符串。
第二,内存字符串:代码字符串在内存中的形式。
第三,正则模式字符串:由Pattern编译内存字符串形成的正则模式字符串。
比如在java代码中表示一个"\$"字符串,应该这样写
String code = "\\$";
System.out.println("code: " + code);
输出结果 code: \$
因为在java代码中"\"表示转义字符,所以第一个"\"表示要转义后面的内容。在内存中,code内存字符串形式就是"\$"。
现在想写一个正则表达式匹配字符串"\$",代码如下:
String code="\\$";
System.out.println("code: " + code);
String patternString ="\\\\\\$";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(code);
while(matcher.find()) {
System.out.println("matcher:" + matcher.group());
}
输出结果 code:\$
matcher:\$
为什么匹配模式的java代码字符串是"\\\\\\$"。code在内存中形式是:\$,那正则模式字符串也应该是\$,在编译为模式字符串前的内存字符串应该是\\\$。正则模式字符串的第一个"\",在内存中应该是"\\"(正则模式中的\表示转义),而$在内存中应该是\$(正则模式串中$表示空白字符,所以需要转义),所以模式字符串在编译前在内存中的形式应该\\\$。内存的\\\$,再转换为java代码,应该是"\\\\\\$"
在使用正则时经常用到捕获组,对于捕获到的组进行字符串替换,需要用到appendReplacement(StringBuffer sb, String replacement)方法。该方法对于第二个参数替换的字符串有特殊要求,如果replacement里有"\"字符串和"$"字符串则必须要进行转义。为什么了?可以看看源代码replacement的源码:
public Matcher appendReplacement(StringBuffer sb, String replacement) {
// If no match, return error
if (first < 0)
throw new IllegalStateException("No match available");
// Process substitution string to replace group references with groups
int cursor = 0;
String s = replacement;
StringBuffer result = new StringBuffer();
while (cursor < replacement.length()) {
char nextChar = replacement.charAt(cursor);
if (nextChar == '\\') {
cursor++;
nextChar = replacement.charAt(cursor);
result.append(nextChar);
cursor++;
} else if (nextChar == '$') {
// Skip past $
cursor++;
// The first number is always a group
int refNum = (int)replacement.charAt(cursor) - '0';
if ((refNum < 0)||(refNum > 9))
throw new IllegalArgumentException(
"Illegal group reference");
cursor++;
// Capture the largest legal group string
boolean done = false;
while (!done) {
if (cursor >= replacement.length()) {
break;
}
int nextDigit = replacement.charAt(cursor) - '0';
if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
break;
}
int newRefNum = (refNum * 10) + nextDigit;
if (groupCount() < newRefNum) {
done = true;
} else {
refNum = newRefNum;
cursor++;
}
}
// Append group
if (group(refNum) != null)
result.append(group(refNum));
} else {
result.append(nextChar);
cursor++;
}
}
// Append the intervening text
sb.append(getSubSequence(lastAppendPosition, first));
// Append the match substitution
sb.append(result.toString());
lastAppendPosition = last;
return this;
}
原来在替换的时候,程序会遍历replacement的每个字符,如果内存字符为'\'则不会把该字符放入到缓存result中而是把后面一个字符直接放入到缓存result中;如果字符为$符号,则会判断$字符后面的是不是数字,如果是数字则会认为是组引用,及把匹配组的字符串加到字符缓存result中。原来字符'\'和字符'$'在replacement中可以认为是关键字有特殊的作用。所以我们在调用此方法之前最好把replacement中"\"转换为"\\","$"转换为"\$"。
现在实验一下,把字符串中"Y123Y324"字符"Y"替换成"$"。
String patternString = "(Y)";
String code = "Y123Y432";
//System.out.println("code:" + code);
String replacement = "$";
replacement = replacement.replaceAll("\\$", "\\\\\\$");
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(code);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
System.out.println(sb.toString());
输出结果:$123$432
至于为什么replaceAll里的第二个参数是这样的"\\\\\\$",其实看源码,replaceAll也是调用了Matcher类里的appendReplacement。分析方法可以参照前面的方法。
分享到:
相关推荐
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它基于模式匹配的概念,能够高效地进行文本搜索、替换和解析。在Java中,正则表达式主要通过`java.util.regex`包来实现,提供了Pattern和Matcher两个核心...
Java正则表达式匹配工具是IT领域中一种强大的文本处理工具,它利用正则表达式(Regular Expression)的规则来查找、替换或者提取文本中的特定模式。正则表达式是一种特殊的字符序列,能够帮助程序员或者用户高效地...
以下是对这些文档标题所涉及的Java正则表达式知识点的详细解释: 1. **正则表达式之道** 这个主题可能涵盖了正则表达式的基础概念,包括元字符、字符类、量词和分组。元字符如`.`代表任意字符,`^`表示行首,`$`...
Java正则表达式是一种强大的文本处理工具,广泛用于验证字符串、查找特定模式和替换文本。在Java中,正则表达式提供了简洁而灵活的方式来处理字符串,使得编程人员能够以更高效的方式实现各种文本操作。 正则表达式...
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许程序员通过模式匹配来查找、替换或分割文本。在Java中,正则表达式是通过`java.util.regex`包提供的API来实现的。本讲解将深入探讨Java正则表达式的...
Java正则表达式是编程语言Java中用于处理字符串和文本的强大工具。它允许开发者通过模式匹配来执行复杂的文本分析和操作。在Java中,正则表达式的操作主要涉及两个核心类:`java.util.regex.Matcher`和`java.util....
Java 正则表达式过滤特殊字符的正则表达式 Java 正则表达式是 Java 语言中的一种强大的文本处理工具,能够对字符串进行复杂的匹配、提取和替换操作。本文将详细介绍 Java 正则表达式在过滤特殊字符方面的应用。 ...
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许程序员通过模式匹配来查找、替换或分割文本。本教程将深入讲解Java中的正则表达式,并提供丰富的实例来帮助开发者理解和应用这些概念。 1. 正则...
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许程序员通过模式匹配来查找、替换或分割文本。正则表达式在各种场景下都有广泛应用,如数据验证、文本提取、搜索替换等。本篇文章将深入探讨Java中的...
Java正则表达式测试器是一款强大的工具,专为在Java环境中进行正则表达式测试而设计。它使得开发者能够在编写和调试正则表达式时节省大量时间和精力,避免了传统方式下反复试错的繁琐过程。这个工具的核心功能是提供...
Java正则表达式是编程语言Java中用于处理字符串的强大工具,它允许我们通过模式匹配来查找、替换或提取文本。这个“java正则表达式检查”小工具专门用于测试正则表达式的有效性,帮助开发者验证自己的正则表达式是否...
Java正则表达式详解 Java中的正则表达式是一个强大的文本处理工具,它允许程序员进行复杂的字符串匹配、查找、替换和分割操作。在Java中,正则表达式是通过`java.util.regex`包来实现的,这个包提供了一系列类,如`...
Java正则表达式是用于处理文本和匹配模式的强大工具,尤其在编程中,它能帮助开发者高效地查找、替换和解析字符串。虽然Java规范在某些版本中才开始内置正则表达式支持,但在等待官方更新的同时,开发人员可以通过第...
例如,以下代码展示了如何使用Java正则表达式检查字符串是否符合社会安全号码的格式: ```java import java.util.regex.*; public class Main { public static void main(String[] args) { String ssn = "123-12...
Java正则表达式是Java编程语言中的一个强大工具,用于处理字符串匹配、查找、替换等操作。它基于Perl风格的正则表达式,为开发者提供了高效且灵活的文本处理能力。在这个“Java正则表达式从入门到精通”的主题中,...
### Java正则表达式基础知识与应用 #### 一、引言 正则表达式是一种强大的文本处理工具,它能够帮助开发者高效地进行字符串的搜索、替换等操作。Java中的正则表达式支持广泛的标准和特性,是进行文本处理任务的理想...
Java正则表达式是编程语言Java中用于处理文本的强大工具,其起源可追溯到神经网络研究,后来由数学家Stephen Kleene发展成一种描述特定文本模式的表达式。正则表达式在各种语言中得到广泛应用,例如Perl、PHP、...