我想知道如何使用java regex实现以下场景:
"*"
示例:
"0000"
将成为"****"
"any text 000 00 more texts"
将成为"any text ***** more texts"
..请注意空格已删除 "any text 000 00 more texts 00"
将成为"any text ***** more texts 00"
"any text 000 00 more texts 00 00"
将成为"any text ***** more texts ****"
"any text 00-00 more texts 00_00"
将成为"any text **** more texts ****"
要查找我尝试过的数字:
(\d*)(?=[^a-bA-Z]*)
和
(\d*)([^a-bA-Z])(\d*)
(\d*)([^a-bA-Z])(\d*)
但即使匹配案例也行不通。
我需要更多地了解如何进行正则表达式操作。
答案 0 :(得分:1)
以下是您可以尝试的方法:
s = s.replaceAll ("\\d{5}", "*****").replaceAll("\\d{4}", "****")
for (int i = 1; i < 5; i++) {
s = s.replaceAll("(\\d{" + i + "})([^A-Za-z]*)(\\d{" + (5 - i) + "})", "*****");
}
for (int i = 1; i < 4; i++) {
s = s.replaceAll("(\\d{" + i + "})([^A-Za-z]*)(\\d{" + (4 - i) + "})", "****");
}
答案 1 :(得分:1)
您可以使用以下内容:
private static final Pattern p = Pattern
.compile( "(?<!\\d[^a-z\\d]{0,10000})"
+ "\\d([^a-z\\d]*\\d){3}([^a-z\\d]*\\d)?"
+ "(?![^a-z\\d]*\\d)", Pattern.CASE_INSENSITIVE);
public static String replaceSpecial(String text) {
StringBuffer sb = new StringBuffer();
Matcher m = p.matcher(text);
while (m.find()) {
m.appendReplacement(sb, m.group(2) == null ? "****" : "*****");
}
m.appendTail(sb);
return sb.toString();
}
用法演示:
System.out.println(replaceSpecial("foo 123 56 78 bar 12 32 abc 000_00"));
System.out.println(replaceSpecial("0000"));
System.out.println(replaceSpecial("any text 00 00 more texts"));
System.out.println(replaceSpecial("any text 000 00 more texts 00"));
System.out.println(replaceSpecial("any text 000 00 more texts 00 00"));
System.out.println(replaceSpecial("any text 00-00 more texts 00_00"));
结果:
foo 123 56 78 bar **** abc *****
****
any text **** more texts
any text ***** more texts 00
any text ***** more texts ****
any text **** more texts ****
思想/解释:
我们希望找到零或更多非数字但非字母字符之间的一系列数字(我们可以通过[^\\da-z]
代表它们,但IMO [^a-z\\d]
看起来更好所以我将使用这种形式)。这个系列的长度是4或5,我们可以写为
digit([validSeparator]*digit){3,4} //1 digit + (3 OR 4 digits) => 4 OR 5 digits
但我们需要有一些方法来识别我们是否匹配4位或5位数,因为我们需要一些方法来决定是否要用4或5个星号替换此匹配。
为此,我将尝试将第5位数字放在单独的组中,并测试该组是否为空。所以我会尝试创建像dddd(d)?
这样的东西。
我是怎么想出来的
"\\d([^a-z\\d]*\\d){3}([^a-z\\d]*\\d)?"
// ^^^^^^^^^^^^^^^ possible 5th digit
现在需要确保我们的正则表达式只匹配左侧或右侧未被任何数字包围的dddd(d)
,因为我们不想匹配任何案例,例如
d ddddd
dddddd
ddddd d
因此我们需要添加测试,以检查在匹配之前(或之后)是否没有数字(和有效的分隔符)。我们可以在这里使用负面观察机制,如
"(?<!\\d[^a-z\\d]{0,10000})"
- 我使用了{0,10000}
代替*
,因为后台需要有一些最大长度,这使我们无法*
。
"(?![^a-z\\d]*\\d)"
所以现在我们需要做的就是组合这些正则表达式(并使其不区分大小写或代替a-z
使用a-zA-Z
)
Pattern p = Pattern.compile( "(?<!\\d[^a-z\\d]{0,10000})"
+ "\\d([^a-z\\d]*\\d){3}([^a-z\\d]*\\d)?"
+ "(?![^a-z\\d]*\\d)", Pattern.CASE_INSENSITIVE);
Rest是Matcher类中appendTail
和appendReplacement
方法的简单用法,它可以让我们动态决定使用什么来替代已建立的匹配(我试着在这里更好地解释它:{{3} })
答案 2 :(得分:1)
尝试:
(?<!\d|\d[_\W])(?=(\d|(?<=\d)[_\W]\d){4,5}(?!\d|[_\W]\d))\d|(?<=(?!^)\G)[_\W]?\d
(?<!\d|\d[_\W])(?=(\d|(?<=\d)[_\W]\d){4,5}(?!\d|[_\W]\d))\d
部分匹配数字,如果:
(?<=(?!^)\G)[_\W]?\d
部分匹配如果:
Java中的示例:
public class RegexExample {
public static void main(String[] args) {
String[] examples = {"0000","any text 000 00 more texts","any text 000 00 more texts 00",
"any text 000 00 more texts 00 00","any text 00-00 more texts 00_00","test 00 00 00 00 00 test"};
for(String example : examples) {
System.out.println(example.replaceAll("(?<!\\d|\\d[_\\W])(?=(\\d|(?<=\\d)[_\\W]\\d){4,5}(?!\\d|[_\\W]\\d))\\d|(?<=(?!^)\\G)[_\\W]?\\d","*"));
}
}
}
带输出:
****
any text ***** more texts
any text ***** more texts 00
any text ***** more texts ****
any text **** more texts ****
test 00 00 00 00 00 test
答案 3 :(得分:0)
试试这个
(?:(?:\d[- _]*){6,})
说明:
(?<num1>\d[- _]?)(?<num2>\d[- _]?)(?<num3>\d[- _]?)(?<num4>\d)(?<num5>[- _]?\d)?
:没有捕获匹配6个以上数字的行
"1-2-3-4-5-6" => no
"1-2-3-4-5" => yes match 1
"1-2-3-4" => yes match 2
"1-2-3" => no
"123456" => no
"12345" => yes match 3
"1234" => yes match 4
"123" => no
foo 123 56 78 bar
:捕获4-5行数。
输入
MATCH 1
num_1 [21-23] `1-`
num_2 [23-25] `2-`
num_3 [25-27] `3-`
num_4 [27-28] `4`
num_5 [28-30] `-5`
MATCH 2
num_1 [50-52] `1-`
num_2 [52-54] `2-`
num_3 [54-56] `3-`
num_4 [56-57] `4`
MATCH 3
num_1 [119-120] `1`
num_2 [120-121] `2`
num_3 [121-122] `3`
num_4 [122-123] `4`
num_5 [123-124] `5`
MATCH 4
num_1 [148-149] `1`
num_2 [149-150] `2`
num_3 [150-151] `3`
num_4 [151-152] `4`
输出:
*
然后用.wrapper{ width:720px; margin: 0 auto; }
替换它们:)