Java 查找随后的一行数字(由非字母字符分隔)并对其进行计数
我想知道如何使用java正则表达式实现以下场景:Java 查找随后的一行数字(由非字母字符分隔)并对其进行计数,java,regex,Java,Regex,我想知道如何使用java正则表达式实现以下场景: 在字符串中查找所有不以字母字符分隔的后续数字,对其进行计数,如果数字数在4到5之间(包括5),则将其替换为“*” 示例: “0000”将变成“****” “任意文本000多个文本”将变为“任意文本******多个文本”。请注意,空格已被删除 “任意文本000多文本00”将变成“任意文本******多文本00” “任意文本000多个文本00”将变为“任意文本******多个文本****” “任何文本00-00更多文本00\u 00”将变成“任
- 在字符串中查找所有不以字母字符分隔的后续数字,对其进行计数,如果数字数在4到5之间(包括5),则将其替换为
“*”
将变成“0000”
“****”
将变为“任意文本000多个文本”
。请注意,空格已被删除“任意文本******多个文本”
将变成“任意文本000多文本00”
“任意文本******多文本00”
将变为“任意文本000多个文本00”
“任意文本******多个文本****”
将变成“任何文本00-00更多文本00\u 00”
“任何文本****更多文本****”
和(\d*)(?=[^a-bA-Z]*)
(\d*)([^a-bA-Z])(\d*)
(\d*)([^a-bA-Z])(\d*)
我需要更多地了解如何执行正则表达式操作。这里有一种方法可以尝试:
s=s.replaceAll(\\d{5},“****”).replaceAll(\\d{4},“****”)
对于(int i=1;i<5;i++){
s=s.replaceAll(“(\\d{i+”})([^A-Za-z]*)(\\d{+(5-i)+“})”,“****”;
}
对于(int i=1;i<4;i++){
s=s.replaceAll(“(\\d{+i+”})([^A-Za-z]*)(\\d{+(4-i)+“})”,“***”);
}
您可以使用以下内容:
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();
}
结果:
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位数字放在单独的组中,并测试该组是否为空。因此,我将尝试创建类似于
ddddd(d)?
的内容
我就是这样想出这个主意的
"\\d([^a-z\\d]*\\d){3}([^a-z\\d]*\\d)?"
// ^^^^^^^^^^^^^^^ possible 5th digit
现在我们需要确保我们的正则表达式只匹配dddddd(d)
,它没有被从左到右的任何数字包围,因为我们不想匹配这样的情况
d ddddd
dddddd
ddddd d
因此,我们需要添加测试来检查匹配之前(或之后)是否没有数字(和有效分隔符)。我们可以在这里使用负面环视机制,如
- (?试试:
试试这个(?<!\d|\d[_\W])(?=(\d|(?<=\d)[_\W]\d){4,5}(?!\d|[_\W]\d))\d|(?<=(?!^)\G)[_\W]?\d
输出:(?:(?:\d[- _]*){6,})|(?<num_1>\d[- _]*)(?<num_2>\d[- _]*)(?<num_3>\d[- _]*)(?<num_4>\d)(?<num_5>[- _]*\d)?
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`
然后将其替换为
:)如果我们有*
?它是否应该被foo 123 56 78 bar
替换,或者我们应该期待类似*
的东西?它不应该被“*”替换。这是。和a。我不知道你的正则表达式知识水平:),这样我只能建议在,(有许多其他链接到伟大的在线资源),以及所谓的社区帖子。@pshemo这就是我不发布它的另一个原因——前瞻边界应该调整。foo*******78 bar
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
(?:(?:\d[- _]*){6,})|(?<num_1>\d[- _]*)(?<num_2>\d[- _]*)(?<num_3>\d[- _]*)(?<num_4>\d)(?<num_5>[- _]*\d)?
"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
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`