我正在尝试从银行对帐单中提取交易并将其放入数据库中。
作为第一步,我在statement.txt文件中有我的声明,它包含以下示例数据。
...some lines of text
11/29/16 Online scheduled transfer to SAV 8075 Confirmation# 1098489998 -500.00
11/29/16 KEEP THE CHANGE TRANSFER TO ACCT 8075 FOR 11/29/16 -0.09
11/30/16 CHECKCARD 1129 TONNELLE MART PROFESSIO NORTH BERGEN NJ
24055236335400648000752
-17.76
11/30/16 CHECKCARD 1129 STATE FARM 800-956-6310 IL 24610436334004074264281 RECURRING -297.09
...some more transactions and text.
如您所见,一些数据正在流入下一行。 我正在将这些行读成流,如下所示。
Stream<String> lines = Files.lines(Paths.get("statement.txt"),Charset.defaultCharset());
现在,无论是否有Streams,我如何实现以下目标?
以下是我的日期和金额的正则表达式:
String date= "^[0-3]?[0-9]/[0-3]?[0-9]/(?:[0-9]{2})?[0-9]{2}\\s.";
String amount = "^-?\\d+(\\.\\[0-9][0-9]).";
答案 0 :(得分:2)
你问了很多东西。我建议你把它们分解一下,这将有助于你看到你所要求的并不是太难:文件读取,解析,连接,然后文件写入。拆分一切。
我尝试过使用Streams,并尝试使用带有谓词的每个方法。
我对文件写作或返回的意思不太清楚:
- 任何应该添加到另一个文本文件或arrayList中的行,称为“transactions
”- 当一行分成多个[...]时,这些行应该连接并返回。
醇>
我已将分割线连接到一行,然后您可以根据需要执行任何操作。
这是我的(完全未经测试,但正在编译)代码:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestStream {
public void main(String[] argc) throws IOException{
Stream<String> lineStream = streamFile("testFile.txt"); // Stream Input text
List<String> transactionList = new ArrayList<>(); // Prepare result list
Map<Boolean, List<String>> transactionstream = lineStream.collect(Collectors.partitioningBy(s -> s.matches("^[0-3]?[0-9]/[0-3]?[0-9]/(?:[0-9]{2})?[0-9]{2}\\s")));
transactionstream.forEach((success, transactionContent) -> {
if(!success)
return;
String concat = transactionContent.stream().collect(Collectors.joining());
transactionList.add(concat);
});
}
public Stream<String> streamFile(final String filename) throws IOException {
Stream<String> stream = Files.lines(Paths.get(filename));
return stream;
}
}
基本上我:
Map<Boolean, List<String>>
,其中boolean表示匹配,List包含连续的行,其中只有第一行以日期开头(即它的事务)transactionList
中。我认为不可能充分发挥Stream
s的潜力来完成这项任务,因为:
Streams
所以Streams将不会是懒惰的&amp;高效。但它比手动解决方案短得多。
警告:我没有添加任何分隔符来连接这些行,这可能会弄乱内容。您可能需要一个分隔符。幸运的是,您可以使用其他 Collector.joining()
方法做到这一点!
答案 1 :(得分:1)
我在下面解决了它...它不完美..帮助我提高
将此方法放在任何具有psvm
的类中static ArrayList<String> printMatchers(){
String fileName = "/Users/dhananjayraparla/Desktop/GitHub/Groovy/BankStatementViewer/src/main/resources/Statements.txt";
Pattern date = Pattern.compile("^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]");
Pattern amount = Pattern.compile("-?\\d{0,3},?\\d{0,3}\\.\\d{2}$");
//read file into stream, try-with-resources
String previous=new String();
List<String> lines = null;
try {
lines = Files.readAllLines(Paths.get(fileName));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ArrayList<String> filteredList = new ArrayList<>();
for (int i = 0; i < lines.size(); i++) {
Matcher dt = date.matcher(lines.get(i));
Matcher amt = amount.matcher(lines.get(i));
if ( dt.find() && amt.find() ){
System.out.println( lines.get(i) );
filteredList.add( lines.get(i) );
}
else if (i<lines.size()-2) {
String temp1 = lines.get(i)+" "+lines.get(i+1);
Matcher dt2 = date.matcher(temp1);
Matcher amt2 = amount.matcher(temp1);
String temp2 = lines.get(i)+" "+lines.get(i+1)+" "+lines.get(i+2);
Matcher dt3 = date.matcher(temp2);
Matcher amt3 = amount.matcher(temp2);
if (dt2.find() && amt2.find()) {
System.out.println(temp1);
filteredList.add(temp1);
} else if (dt3.find() && amt3.find()) {
System.out.println(temp2);
filteredList.add(temp2);
}
}
}
try {
Path out = Paths.get("/Users/dhananjayraparla/Desktop/GitHub/Groovy/BankStatementViewer/src/main/resources/filteredTransactionList.txt");
Files.write(out,filteredList,Charset.defaultCharset());
} catch (IOException e) {
e.printStackTrace();
}
return filteredList;
}
正如你所看到的......我写了自己的模式
Pattern date = Pattern.compile("^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]");
Pattern amount = Pattern.compile("-?\\d{0,3},?\\d{0,3}\\.\\d{2}$");
并没有使用Java 8流。
这是我的输入
11/17/16 GAS MART AT BR 11/17 #000157975 PURCHASE GAS MART AT BRO -1.75
continued on the next page
! = 1725 0868 ! October 20, 2016 to November 17, 2016
Page 6 of 6
Withdrawals and other subtractions - continued
Date Description Amount
11/17/16 PLANET FIT DES:CLUB FEES ID:1632102280753 INDN: CO
ID:1710602737 PPD PMT INFO:516-861-2109
-10.00
11/17/16 KEEP THE CHANGE TRANSFER TO FOR 11/17/16 -0.99
Total withdrawals and other subtractions -$4,186.00
Service fees
Date Transaction description Amount
10/20/16 P199657 10/19 #000008705 WITHDRWL 199 FEE
-2.50
这是我的输出
11/17/16 GAS MART AT BR 11/17 #000157975 PURCHASE GAS MART AT BRO NY -1.75
11/17/16 PLANET FIT DES:CLUB FEES ID:1632102280753 INDN: CO ID:1710602737 PPD PMT INFO:516-861-2109 -10.00
11/17/16 KEEP THE CHANGE TRANSFER TO FOR 11/17/16 -0.99
10/20/16 P199657 10/19 #000008705 WITHDRWL 199 FEE -2.50
我想知道如何使用流来获得此结果