Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查找随后的一行数字(由非字母字符分隔)并对其进行计数_Java_Regex - Fatal编程技术网

Java 查找随后的一行数字(由非字母字符分隔)并对其进行计数

Java 查找随后的一行数字(由非字母字符分隔)并对其进行计数,java,regex,Java,Regex,我想知道如何使用java正则表达式实现以下场景: 在字符串中查找所有不以字母字符分隔的后续数字,对其进行计数,如果数字数在4到5之间(包括5),则将其替换为“*” 示例: “0000”将变成“****” “任意文本000多个文本”将变为“任意文本******多个文本”。请注意,空格已被删除 “任意文本000多文本00”将变成“任意文本******多文本00” “任意文本000多个文本00”将变为“任意文本******多个文本****” “任何文本00-00更多文本00\u 00”将变成“任

我想知道如何使用java正则表达式实现以下场景:

  • 在字符串中查找所有不以字母字符分隔的后续数字,对其进行计数,如果数字数在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
    ?它是否应该被
    *
    替换,或者我们应该期待类似
    foo*******78 bar
    的东西?它不应该被“*”替换。这是。和a。我不知道你的正则表达式知识水平:),这样我只能建议在,(有许多其他链接到伟大的在线资源),以及所谓的社区帖子。@pshemo这就是我不发布它的另一个原因——前瞻边界应该调整。
    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`