Java 使用正则表达式屏蔽以下格式

Java 使用正则表达式屏蔽以下格式,java,regex,Java,Regex,我试图编写一个正则表达式来屏蔽下面的字符串。下面的例子 输入 A1../D//FASDFAS--DFASD//.F 输出(跳过前五个和最后两个字母数字) 我正在尝试使用下面的正则表达式 ([A-Za-z0-9]{5})(.*)(.{2}) 任何帮助都将不胜感激。如果您想使用单个正则表达式,您可以使用 text = text.replaceAll("(\\G(?!^|(?:[0-9A-Za-z][^0-9A-Za-z]*){2}$)|^(?:[^0-9A-Za-z]*[0-9A-Za-z]){5

我试图编写一个正则表达式来屏蔽下面的字符串。下面的例子

输入

A1../D//FASDFAS--DFASD//.F
输出(跳过前五个和最后两个字母数字)

我正在尝试使用下面的正则表达式 ([A-Za-z0-9]{5})(.*)(.{2})


任何帮助都将不胜感激。

如果您想使用单个正则表达式,您可以使用

text = text.replaceAll("(\\G(?!^|(?:[0-9A-Za-z][^0-9A-Za-z]*){2}$)|^(?:[^0-9A-Za-z]*[0-9A-Za-z]){5}).", "$1*");
或者,使用POSIX字符类
Alnum

text = text.replaceAll("(\\G(?!^|(?:\\p{Alnum}\\P{Alnum}*){2}$)|^(?:\\P{Alnum}*\\p{Alnum}){5}).", "$1*");
请参阅和。如果计划用星号替换任何代码点而不是单个代码单元,请将
替换为
\P{M}\P{M}*+
“\\P{M}\\P{M}*+”

要使
匹配换行符,请在图案开头添加
(?s)

详细信息

A1../D//FA***********D//.F
  • (\G(?)(?:[0-9A-Za-z][^0-9A-Za-z]*){2}$)|((:[0-9A-Za-z]*[0-9A-Za-z]){5})
    -
    • \G(?)(?:[0-9A-Za-z][^0-9A-Za-z]*){2}$)
      -成功匹配后的一个位置,后面没有出现两次字母数字字符,后面有0个或更多字符,而不是字母数字字符
    • |
      -或
    • ^(?:[^0-9A-Za-z]*[0-9A-Za-z]){5}
      -字符串开头,后跟五次出现的0个或多个非字母数字字符,后跟一个字母数字字符
  • -除换行字符以外的任何代码单元(如果使用
    \P{M}\P{M}*+
    -任何代码点)

您可以通过使用匹配多个组的
模式和
匹配器来解决问题:

String str = "A1../D//FASDFAS--DFASD//.F";
Pattern pattern = Pattern.compile("(.*?\\/\\/..)(.*?)(.\\/\\/.*)");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
    str = matcher.group(1)
            + matcher.group(2).replaceAll(".", "*")
            + matcher.group(3);
}
细节

  • (.*?\/\\/..)
    第一组匹配所有内容,直到
    /
  • (.*)
    第二组匹配第一组和第三组之间的所有内容
  • (.\/\\/.*)
    第三组匹配
    /
    前最后一个字符后的所有内容,直到字符串结束
输出

A1../D//FA***********D//.F

我认为这个解决方案更可读。

通常,字符串的中间字符的掩码可以使用否定的查找后面的代码>(和正的前瞻性组<代码>(?=)< /代码>。 但在这种情况下,由于前五个字母数字字符之间的非字母数字字符数量不可预测(

/
A1../D//FA
中),查找组没有明显的最大长度,因此无法使用

子字符串
方法可作为无法使用负查找组的变通方法:

String str = "A1../D//FASDFAS--DFASD//.F";
int start = str.replaceAll("^((?:\\W{0,}\\w{1}){5}).*", "$1").length();
String maskedStr = str.substring(0, start) +
    str.substring(start).replaceAll(".(?=(?:\\W{0,}\\w{1}){2})", "*");
System.out.println(maskedStr);
// A1../D//FA***********D//.F
但是最简单的方法是使用
java.util.regex.Pattern
java.util.regex.Matcher

String str = "A1../D//FASDFAS--DFASD//.F";
Pattern pattern = Pattern.compile("^((?:\\W{0,}\\w{1}){5})(.+)((?:\\W{0,}\\w{1}){2})");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
  String maskedStr = matcher.group(1) +
      "*".repeat(matcher.group(2).length()) +
      matcher.group(3);
  System.out.println(maskedStr); 
  // A1../D//FA***********D//.F
}
  • \W{0,}
    -0个或更多非字母数字字符
  • \w{1}
    -正好是1个字母数字字符
  • (\W{0,}\W{1}){5}
    -5个字母数字字符和介于两者之间的任意数量的字母数字字符
  • (?:\W{0,}\W{1}){5}
    -不作为组捕获
  • ^((?:\\W{0,}\\W{1}){5})(.+)((?:\\W{0,}\\W{1}){2})$
    -前五个字母数字字符的子字符串(第1组),其他所有字符(第2组),最后两个字母数字字符的子字符串(第3组)

你能告诉我们你的努力吗“([A-Za-z0-9]{5})(.*)(.{2})”我正在使用这个正则表达式