gpt4 book ai didi

java - 如何在Java中跳过Regex的某些部分?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:46:10 25 4
gpt4 key购买 nike

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

这是从文件中摘录的:

enter image description here

我需要提取:

12000

解析的行如下所示:

Bolighus fullverdi 4374720 121000 11806

我找不到一种方法来跳过前7个数字(4 374 720)。

我试着玩一些类似的游戏:

(\ d +){3}

它找到2个匹配项:

enter image description here

正则表达式在这种情况下如何获得价值:

\ 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;
}

但是,我发现了一个关键问题。

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

enter image description here

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

解析后的行结尾为:

313400 6 000 370

产生不正确的结果:

313400、6000370

代替

313400、6000、370

更新2

考虑下一种情况:

enter image description here

我们的行将如下所示:

Innbo Ekstra Nordea 1500万1302

结果将产生3组:

1500000
1个
302

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

如何解决此问题?

最佳答案

您的电话号码有一种特殊的模式,可用于为您解决问题。如果您注意到此字符串中的任何空格,紧跟三位数字的空格都可以删除,以将构成实际数字的数字统一起来,从而使该字符串,

Bolighus fullverdi 4 374 720 12 000 11 806

为此,
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");
}
}

哪个输出,
Transformed string: Bolighus fullverdi 4374720 12000 11806
12000

希望这可以帮助!

编辑:

这是此正则表达式 \D*\d+\s+(\d+)\s+\d+的解释,用于从转换后的字符串中捕获所需数据。
Bolighus fullverdi 4374720 12000 11806
  • .*->匹配数字之前的任何数据,此处匹配Bolighus fullverdi
  • \d+->匹配一个或多个数字,此处匹配4374720
  • \s+->匹配数字之间存在的一个或多个空格。
  • (\d+)->匹配一个或多个数字并将其捕获到与12000匹配的组1中
  • \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
    希望能澄清这一点,让我知道您是否还有其他需要。

    编辑2

    为了覆盖后面的字符串,
    Andre bygninger 313 400 6 000 370

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

    在字符串中还有更多 423数字,那么它将被捕获为以下数字,

    313400、6000370、423

    因为它不知道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();
    }
    }

    此代码根据需要输出以下输出,
    For string: Bolighus fullverdi 4 374 720 12 000 11 806
    4374720
    12000
    11806

    For string: Andre bygninger 313 400 6 000 370
    313400
    6000
    370

    这是正则表达式的解释,
    .*?(\\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})*)->此模式尝试捕获第一个数字,该数字可以以1到3位数字开头,后跟空格,而恰好3位数字和“空格加3位数字”总共可以出现0次或多次。
  • \\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})*匹配一个空格和 400,它停止,因为下一个数据是空格,后跟 6,它只是一个数字而不是三个数字。

    同样,第二组 (\\d{1,3}(?:\\s+\\d{3})*)首先匹配 6(因为 \\d{1,3}),然后 (?:\\s+\\d{3})*)匹配 000并停止,因为它需要保留一些数据以匹配第3组,否则正则表达式匹配将失败。

    最后,第三组匹配 370,因为这是剩下的唯一数据。因此, \\d{1,3}匹配 370,然后 (?:\\s+\\d{3})*不匹配任何东西,因为它是零个或多个组。

    希望能澄清。让我知道您是否还有任何疑问。

    编辑2018年12月22日仅将数字分为两组

    当您想对来自此字符串的数据进行分组时,
    Innbo Ekstra Nordea 1 500 000 1 302

    分为两组具有 15000001302的数字,您的正则表达式只需要具有两组,就像我在评论中回答的那样,
    .*?(\\d{1,3}(?:\\s+\\d{3})*)\\s*(\\d{1,3}(?:\\s+\\d{3})*)

    这是相同的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})*)");
    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

    关于java - 如何在Java中跳过Regex的某些部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53503796/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com