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