java正则表达式转义

电脑杂谈  发布时间:2020-07-14 12:12:34  来源:网络整理

java正则表达式语法_java正则表达式转义_java正则表达式转义

[size = medium]

在学习Java正则表达式时,我遇到了三个问题.

1,java字符串和常规模式字符串非常不清楚

2. 捕获组的概念包含在正则化中,并且字符串替换也可以在捕获的组上执行,也就是说,appendReplacement(StringBuffer sb,字符串替换)方法的原理尚不清楚

3. 为什么在调用appendReplacement(StringBuffer sb,String replace)方法之前,需要在替换中转义“ \”和“ $”字符.

Java正则表达式通常是对字符串的操作. 我个人了解,在正则表达式中,字符串具有三个基本概念:

java正则表达式语法_java正则表达式转义_java正则表达式转义

首先,代码字符串: 用Java文件编写的字符串.

第二,内存字符串: 内存中代码字符串的形式.

第三种常规模式字符串: 由模式编译的内存字符串形成的常规模式字符串.

例如,java代码中的“ \ $”字符串应这样写

[/ size]


String code = "\\$";
System.out.println("code: " + code);

java正则表达式语法_java正则表达式转义_java正则表达式转义

[size = medium]

输出结果代码: \ $

因为“ \”表示Java代码中的转义字符,所以第一个“ \”表示转义以下内容. 在内存中,代码存储字符串形式为“ \ $”.

现在我要编写一个匹配字符串“ \ $”的正则表达式,代码如下:

[/ size]


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());
}

java正则表达式语法_java正则表达式转义_java正则表达式转义

[size = medium]

输出结果代码: \ $

匹配项: \ $

为什么与模式匹配的Java代码字符串为[color = red]“ \\\\\\\ $” [/ color]. 内存中的代码形式为: \ $,则常规模式字符串也应为\ $,编译为模式字符串之前的内存字符串应为\\\ $. 常规模式字符串的第一个“ \”在内存中应为“ \\”(常规模式下的\表示转义),而$在内存中应为\ $(常规模式字符串中的$表示空白字符),因此需要进行转义),因此编译前内存中模式字符串的形式应为\\\ $. \\\ $的内存,然后转换为Java代码,它应该是[color = red]“ \\\\\\\ $” [/ color]

使用正则化时通常使用捕获组. 对于捕获组的字符串替换,需要appendReplacement(StringBuffer sb,字符串替换)方法. 此方法对用第二个参数替换的字符串有特殊要求. 如果替换中有“ \”字符串和“ $”字符串,则必须对其进行转义. 为什么?您可以看一下替换源代码的源代码:

[/ size]

java正则表达式语法_java正则表达式转义_java正则表达式转义


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;
}

[size = medium]

事实证明java正则表达式转义,替换时,程序将遍历替换的每个字符. 如果存储字符为“ \”,则不会将字符放入缓存结果中,而是将下一个字符直接放入缓存结果中. 如果字符是$符号java正则表达式转义,它将判断$字符是否是数字. 如果是数字,它将被视为组引用,并且与该组匹配的字符串将被添加到字符缓存结果中. 事实证明,字符'\'和字符'$'在替换中可以视为特殊关键字. 因此,在调用此方法之前,最好将替换的“ \”转换为“ \\”,将“ $”转换为“ \ $”.

现在进行实验,将字符串中的“ Y123Y324”字符“ Y”替换为“ $”.

[/ size]


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());

[size = medium]

输出结果: $ 123 $ 432

至于为什么replaceAll中的第二个参数是这个“ \\\\\\\ $”,实际上是在查看源代码,replaceAll也调用Matcher类中的appendReplacement. 分析方法可以参考以前的方法.

[/ size]


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-279985-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...