如何使用 Java 和正则表达式正确排序文件条目
How to sort files entries correctly using Java and regex
我有一个包含以下条目的文本文件“unsorted.txt”输入:
37060635563
37067264426
37061457700
37067116332
37068672376
37068669157
我希望Java按以下方式在输出文件“sorted.txt”中整理和格式化这些数字。
+370 606 35563
+370 614 57700
+370 686 69157
+370 686 72376
+370 671 16332
+370 672 64426
我已经制作了排序 Java 代码,但它只生成一个条目,我找不到为什么?
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
public class PhoneSort {
public static void main(String[] args) {
final String regex = "(\\d{3})(\\d{3})(\\d*)";
final String subst = "+ ";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
File us = new File("unsorted.txt");
File st = new File("sorted.txt");
String result = "";
try (Scanner sc = new Scanner(us)){
while (sc.hasNextLine()) {
try (FileWriter writer = new FileWriter(st)) {
writer.write(pattern.matcher(sc.nextLine()).replaceAll(subst));
} catch(IOException e){}
}
}
catch (IOException e){}
}
}
如果您想知道为什么您的代码只运行一次,那么您需要进行一些调试,并且需要将任何捕获的异常打印到控制台,以便您可以了解您的代码失败的原因 catch (IOException e){e.printStackTrace();}
。永远不要只使用错误,除非你确切地知道你在做什么以及如果出现问题会发生什么。
现在我们有两个问题之一,第一个是您的代码失败,如果是这样,则打印的错误将显示您的文件编写器存在问题,这可能意味着您需要关闭每次写入后写入文件,但这会产生不同的问题(见下文)。
但是,更有可能的问题是您每次都创建一个新的 FileWriter 并覆盖您以前的文件。要解决这个问题,您需要在 while 循环之外声明您的文件编写器,而不是每次都尝试创建一个新文件编写器。
以下应该有效,请注意我们现在如何将错误打印到控制台,以及我们如何只创建一次 FileWriter:
//We can also add the true flag to append data to the file writer
try (Scanner sc = new Scanner(us);
FileWriter writer = new FileWriter(st, true);){
while (sc.hasNextLine()) {
writer.write(pattern.matcher(sc.nextLine()).replaceAll(subst));
}
writer.close();
}
catch (IOException e){
e.printStackTrace();
}
这是一个具有所需结果的工作示例
public static void main(String[] args) {
final String regex = "(\d{3})(\d{3})(\d*)";
final String subst = "+ ";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
File us = new File("unsorted.txt");
File st = new File("sorted.txt");
try (BufferedReader reader = new BufferedReader(new FileReader(us));
BufferedWriter writer = new BufferedWriter(new FileWriter(st))) {
reader.lines().sorted()
.map(r -> pattern.matcher(r).replaceAll(subst))
.forEach(res -> {
try {
writer.write(res);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
我写这个答案是假设你希望输出是,
+370 606 35563
+370 614 57700
+370 671 16332
+370 672 64426
+370 686 69157
+370 686 72376
我的方法不使用正则表达式,而是将文件读入内存。
- 将文件中的所有行读入
List
。
- 根据要求对以上列表进行排序。 (按前三位排序-如果相同,则按后三位排序。即使相等,也按其余位排序)。
- 将排序后的列表写入结果文件。
Path path = Paths.get("<fill_the_path>/unsorted.txt");
List<String> lines = Files.readAllLines(path);
List<String> sortedList = sort(lines);
Files.write(Paths.get("<fill_the_path>/sorted.txt"),
format(sortedList),
StandardOpenOption.CREATE);
private List<String> sort(List<String> lines) {
Comparator<String> comparator = Comparator.comparing((String s) -> Integer.valueOf(s.substring(0, 3)))
.thenComparing(s -> Integer.valueOf(s.substring(3, 6)))
.thenComparing(s -> Integer.valueOf(s.substring(6)));
return lines.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
private List<String> format(List<String> lines) {
return lines.stream()
.map(this::formatLine)
.collect(Collectors.toList());
}
private String formatLine(String line) {
return "+" +
line.substring(0, 3) + " " +
line.substring(3, 6) + " " +
line.substring(6);
}
注意:您可以将每行转换为 Long
并使用 Comparator.comparingLong
(如果该值适合 long
)。
return lines.stream()
.sorted(Comparator.comparingLong(Long::valueOf))
.collect(Collectors.toList());
我有一个包含以下条目的文本文件“unsorted.txt”输入:
37060635563
37067264426
37061457700
37067116332
37068672376
37068669157
我希望Java按以下方式在输出文件“sorted.txt”中整理和格式化这些数字。
+370 606 35563
+370 614 57700
+370 686 69157
+370 686 72376
+370 671 16332
+370 672 64426
我已经制作了排序 Java 代码,但它只生成一个条目,我找不到为什么?
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
public class PhoneSort {
public static void main(String[] args) {
final String regex = "(\\d{3})(\\d{3})(\\d*)";
final String subst = "+ ";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
File us = new File("unsorted.txt");
File st = new File("sorted.txt");
String result = "";
try (Scanner sc = new Scanner(us)){
while (sc.hasNextLine()) {
try (FileWriter writer = new FileWriter(st)) {
writer.write(pattern.matcher(sc.nextLine()).replaceAll(subst));
} catch(IOException e){}
}
}
catch (IOException e){}
}
}
如果您想知道为什么您的代码只运行一次,那么您需要进行一些调试,并且需要将任何捕获的异常打印到控制台,以便您可以了解您的代码失败的原因 catch (IOException e){e.printStackTrace();}
。永远不要只使用错误,除非你确切地知道你在做什么以及如果出现问题会发生什么。
现在我们有两个问题之一,第一个是您的代码失败,如果是这样,则打印的错误将显示您的文件编写器存在问题,这可能意味着您需要关闭每次写入后写入文件,但这会产生不同的问题(见下文)。
但是,更有可能的问题是您每次都创建一个新的 FileWriter 并覆盖您以前的文件。要解决这个问题,您需要在 while 循环之外声明您的文件编写器,而不是每次都尝试创建一个新文件编写器。
以下应该有效,请注意我们现在如何将错误打印到控制台,以及我们如何只创建一次 FileWriter:
//We can also add the true flag to append data to the file writer
try (Scanner sc = new Scanner(us);
FileWriter writer = new FileWriter(st, true);){
while (sc.hasNextLine()) {
writer.write(pattern.matcher(sc.nextLine()).replaceAll(subst));
}
writer.close();
}
catch (IOException e){
e.printStackTrace();
}
这是一个具有所需结果的工作示例
public static void main(String[] args) {
final String regex = "(\d{3})(\d{3})(\d*)";
final String subst = "+ ";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
File us = new File("unsorted.txt");
File st = new File("sorted.txt");
try (BufferedReader reader = new BufferedReader(new FileReader(us));
BufferedWriter writer = new BufferedWriter(new FileWriter(st))) {
reader.lines().sorted()
.map(r -> pattern.matcher(r).replaceAll(subst))
.forEach(res -> {
try {
writer.write(res);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
我写这个答案是假设你希望输出是,
+370 606 35563
+370 614 57700
+370 671 16332
+370 672 64426
+370 686 69157
+370 686 72376
我的方法不使用正则表达式,而是将文件读入内存。
- 将文件中的所有行读入
List
。 - 根据要求对以上列表进行排序。 (按前三位排序-如果相同,则按后三位排序。即使相等,也按其余位排序)。
- 将排序后的列表写入结果文件。
Path path = Paths.get("<fill_the_path>/unsorted.txt");
List<String> lines = Files.readAllLines(path);
List<String> sortedList = sort(lines);
Files.write(Paths.get("<fill_the_path>/sorted.txt"),
format(sortedList),
StandardOpenOption.CREATE);
private List<String> sort(List<String> lines) {
Comparator<String> comparator = Comparator.comparing((String s) -> Integer.valueOf(s.substring(0, 3)))
.thenComparing(s -> Integer.valueOf(s.substring(3, 6)))
.thenComparing(s -> Integer.valueOf(s.substring(6)));
return lines.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
private List<String> format(List<String> lines) {
return lines.stream()
.map(this::formatLine)
.collect(Collectors.toList());
}
private String formatLine(String line) {
return "+" +
line.substring(0, 3) + " " +
line.substring(3, 6) + " " +
line.substring(6);
}
注意:您可以将每行转换为 Long
并使用 Comparator.comparingLong
(如果该值适合 long
)。
return lines.stream()
.sorted(Comparator.comparingLong(Long::valueOf))
.collect(Collectors.toList());