Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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_Pattern Matching - Fatal编程技术网

如何跳过Java中正则表达式的某些部分?

如何跳过Java中正则表达式的某些部分?,java,regex,pattern-matching,Java,Regex,Pattern Matching,我有一些pdf文件,程序逐行读取 以下是从文件中剪下的: 我需要摘录: 12000 解析的行如下所示: 博利胡斯富尔迪43747201200011806 我找不到跳过前7个数字的方法(4374720) 我试着玩一些匹配的游戏,比如: (\d+{3} 它找到2个匹配项: Regex在这种情况下如何获取值: \d+000 但是我想从正则表达式中省略000。在不同的文档中,它将失败 如何解决这个问题? 也许你可以提出其他解决这个问题的方法 更新: 通过@PushpeshKumarRajwanshi

我有一些pdf文件,程序逐行读取

以下是从文件中剪下的:

我需要摘录:

12000

解析的行如下所示:

博利胡斯富尔迪43747201200011806

我找不到跳过前7个数字的方法(
4374720

我试着玩一些匹配的游戏,比如:

(\d+{3}

它找到2个匹配项:

Regex在这种情况下如何获取值:

\d+000

但是我想从正则表达式中省略
000
。在不同的文档中,它将失败

如何解决这个问题?

也许你可以提出其他解决这个问题的方法

更新:

通过@PushpeshKumarRajwanshi回答,大部分工作都完成了:

public static String groupNumbers(String pageLine) {
    String transformedLine = pageLine.replaceAll(" (?=\\d{3})", StringUtils.EMPTY);
    log.info("TRANSFORMED LINE: \n[{}]\nFrom ORIGINAL: \n[{}]", transformedLine, pageLine);
    return transformedLine;
}

public static List<String> getGroupedNumbersFromLine(String pageLine) {
    String groupedLine = groupNumbers(pageLine);
    List<String> numbers = Arrays.stream(groupedLine.split(" "))
            .filter(StringUtils::isNumeric)
            .collect(Collectors.toList());
    log.info("Get list of numbers: \n{}\nFrom line: \n[{}]", numbers, pageLine);
    return numbers;
}
公共静态字符串组号(字符串页线){
字符串transformedLine=pageLine.replaceAll((?=\\d{3})”,StringUtils.EMPTY;
log.info(“转换行:\n[{}]\n来自原始:\n[{}]”,转换行,页面行);
返回转换线;
}
公共静态列表getGroupedNumbersFromLine(字符串页线){
字符串groupedLine=组编号(页码);
列表编号=Arrays.stream(groupedLine.split(“”)
.filter(StringUtils::isNumeric)
.collect(Collectors.toList());
log.info(“获取编号列表:\n{}\n从行:\n[{}]”,编号,页码);
返回号码;
}
然而,我发现了一个关键问题

有时pdf文件可能如下所示:

其中最后3位数字是一个单独的数字

并且解析的行以:

3134006000370

这会产生不正确的结果:

3134006000370

而不是

3134006000370

更新2

考虑下一种情况:

我们的产品线如下所示:

Innbo Ekstra Nordea 1 500 000 1 302

结果将产生3组:

1500000
1
302

事实上,我们只有第二组输入缺失。 如果缺少第二组,是否可以使正则表达式更灵活?


如何修复这种行为?

您的号码有一种特殊的模式,可以用来为您解决问题。如果你注意到,这个字符串中的任何空格后面紧跟着三位数字,都可以被删除,以统一形成实际数字的数字,这将使这个字符串

Bolighus fullverdi 4 374 720 12 000 11 806
Innbo Ekstra Nordea 1 500 000 1 302
对此,

Bolighus fullverdi 4374720 12000 11806
因此,您可以使用这个正则表达式轻松地捕获第二个数字

.*\d+\s+(\d+)\s+\d+
捕获第2组

下面是一个同样的示例java代码

public static void main(String[] args) {
    String s = "Bolighus fullverdi 4 374 720 12 000 11 806";
    s = s.replaceAll(" (?=\\d{3})", "");
    System.out.println("Transformed string: " + s);
    Pattern p = Pattern.compile(".*\\d+\\s+(\\d+)\\s+\\d+");
    Matcher m = p.matcher(s);
    if (m.find()) {
        System.out.println(m.group(1));
    } else {
        System.out.println("Didn't match");
    }
}
public static void main(String[] args) throws Exception {
    Pattern p = Pattern
            .compile(".*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)");
    List<String> list = Arrays.asList("Innbo Ekstra Nordea 1 500 000 1 302");

    for (String s : list) {
        Matcher m = p.matcher(s);
        if (m.matches()) {
            System.out.println("For string: " + s);
            System.out.println(m.group(1).replaceAll(" ", ""));
            System.out.println(m.group(2).replaceAll(" ", ""));
        } else {
            System.out.println("For string: '" + s + "' Didn't match");
        }
        System.out.println();
    }
}
哪些输出

Transformed string: Bolighus fullverdi 4374720 12000 11806
12000
希望这有帮助

编辑:

下面是这个regex
\D*\D+\s+(\D+)\s+\D+
用于从转换的字符串捕获所需数据的解释

Bolighus fullverdi 4374720 12000 11806
  • *
    -->匹配数字之前的任何数据,在这里它匹配
    Bolighus fullverdi
  • \d+
    -->匹配一个或多个数字,在这里它匹配
    4374720
  • \s+
    -->匹配数字之间的一个或多个空格
  • (\d+)
    -->匹配一个或多个数字,并将其捕获到组1中匹配的
    12000
  • \s+
    -->匹配数字之间的一个或多个空格
  • \d+
    -->匹配一个或多个数字,这里它匹配
    11806
由于OP想要捕捉第二个数字,因此我只对第二个\d+进行分组(在预期的捕捉部分加上括号),但如果您想要捕捉第一个数字或第三个数字,您可以简单地将它们分组,如下所示

\D*(\d+)\s+(\d+)\s+(\d+)
然后在java代码中,调用

m.group(1)
将给出第1组编号,即
4374720

m.group(2)
将给出第2组编号,即
12000

m.group(3)
将给出第3组编号
11806

希望这澄清,让我知道,如果你需要进一步的

Edit2

用于覆盖以下字符串的情况

Andre bygninger 313 400 6 000 370
为了捕获313400、6000和370,我必须改变解决方案的方法。在这种方法中,我将不转换字符串,而是用空格捕捉数字,一旦捕捉到所有三个数字,将删除它们之间的空格。此解决方案适用于旧字符串以及上面的新字符串,我们希望将最后三位数字
370
捕获为第三个数字。但假设我们有以下情况

Andre bygninger 313 400 6 000 370 423
如果字符串中还有更多的
423
位,那么它将被捕获为以下数字

3134006000370423

因为它不知道370应该变成6000还是423。所以我用一种方法来解决这个问题,最后三个数字被捕获为第三个数字

下面是一个可以使用的java代码

public static void main(String[] args) throws Exception {
    Pattern p = Pattern
            .compile(".*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)");
    List<String> list = Arrays.asList("Bolighus fullverdi 4 374 720 12 000 11 806",
            "Andre bygninger 313 400 6 000 370");

    for (String s : list) {
        Matcher m = p.matcher(s);
        if (m.matches()) {
            System.out.println("For string: " + s);
            System.out.println(m.group(1).replaceAll(" ", ""));
            System.out.println(m.group(2).replaceAll(" ", ""));
            System.out.println(m.group(3).replaceAll(" ", ""));
        } else {
            System.out.println("For string: '" + s + "' Didn't match");
        }
        System.out.println();
    }
}
下面是对正则表达式的解释

.*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)
  • *?
    -->匹配并使用数字之前的任何输入
  • (\\d{1,3}(?:\\s+\\d{3})*)
    -->此模式尝试捕获第一个数字,该数字可以从一到三位数字开始,后跟空格,正好三位数字和“空格加三位数字”可以出现零次或多次
  • \\s*
    -->后跟零个或多个空格
然后,同一组
(\\d{1,3}(?:\\s+\\d{3})*)
再重复两次,这样它就可以捕获三组中的数字

因为我已经分了三组比赛,所以比赛必须分三组进行,这样比赛才能成功。例如,这里是捕获该输入的机制

Andre bygninger 313 400 6 000 370
首先,
*?
匹配
“Andre bygninger”
。然后第一组
(\\d{1,3}(?:\\s+\\d{3})*
首先匹配313(因为
\\d{1,3}
),然后
(?:\\s+\\d{3})*
匹配a
.*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)
public static void main(String[] args) throws Exception {
    Pattern p = Pattern
            .compile(".*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)");
    List<String> list = Arrays.asList("Innbo Ekstra Nordea 1 500 000 1 302");

    for (String s : list) {
        Matcher m = p.matcher(s);
        if (m.matches()) {
            System.out.println("For string: " + s);
            System.out.println(m.group(1).replaceAll(" ", ""));
            System.out.println(m.group(2).replaceAll(" ", ""));
        } else {
            System.out.println("For string: '" + s + "' Didn't match");
        }
        System.out.println();
    }
}
For string: Innbo Ekstra Nordea 1 500 000 1 302
1500000
1302
.*\d\s\d{3}\s\d{3}\s(\d+\s+\d+)\s.*. 
^^ matches all the words from the first column  
   ^^^^^^^^^^^^^^^^ - matches the 7 digits and 2 spaces in the 2nd column. 
                  ^^ matches the space(s) between the columns. 
                     ^^^^^^^^^ matches the 2 sets of numbers with a space(12 000) in your example.
public static void main(String[] args) {
    String string = "Bolighus fullverdi 4 374 720 12 000 11 806";
    // Because it's a java string, back-slashes need to be escaped - hence the double \\
    String result = string.replaceAll(".*\\d\\s\\d{3}\\s\\d{3}\\s(\\d+\\s+\\d+)\\s+.*", "$1");
    System.out.println(result);
}