我有一個結構類似于表格的檔案,我需要決議檔案,然后讀取并映射到我的 POCO 類。該檔案如下所示:
Financial Institution : LOREMIPSOM - 019223
FX Settlement Date : 10.02.2021
Reconciliation File ID : 801-288881-0005543759-00001
Transaction Currency : AZN
Reconciliation Currency : USD
-------------------------------------- -------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------- ---------------------
! Settlement Category ! Transaction Amount ! Reconciliation Amnt ! Fee Amount ! Transaction Amount ! Reconciliation Amnt ! Fee Amount ! Count ! Net Value !
! ! Credit ! Credit ! Credit ! Debit ! Debit ! Debit ! Total ! !
-------------------------------------- -------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------- ---------------------
! MC Acq Fin Detail ATM Out 5.00 3.57 49.75 0.00 0.00 0.00 31 3.32 !
! MC Acq Fin Detail Retail Out 5.40 262.01 0.00 0.00 0.00 -3.96 10 258.05 !
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Totals : 10.40 265.58 49.75 0.00 0.00 -3.96 41 261.37
Financial Institution : LOREMIPSOM - 019223
FX Settlement Date : 10.02.2021
Reconciliation File ID : 801-288881-0005543759-00002
Transaction Currency : EUR
Reconciliation Currency : USD
-------------------------------------- -------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------- ---------------------
! Settlement Category ! Transaction Amount ! Reconciliation Amnt ! Fee Amount ! Transaction Amount ! Reconciliation Amnt ! Fee Amount ! Count ! Net Value !
! ! Credit ! Credit ! Credit ! Debit ! Debit ! Debit ! Total ! !
-------------------------------------- -------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------- ---------------------
! Fee Collection Inc 0.00 0.00 0.00 0.00 0.00 0.00 0 0.00 !
! Fee Collection Inc 0.00 0.00 0.00 8.00 0.00 0.00 0 0.00 !
! Fee Collection Inc 0.00 0.00 0.00 0.00 0.00 0.00 0 0.00 !
! Fee Collection Inc 0.00 0.00 0.00 -1.00 0.00 0.00 0 0.00 !
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Totals : 0.00 0.00 0.00 7.00 0.00 0.00 0 0.00
我在考慮手動決議它,我想也許有更好的方法..關于決議資料,所以我需要所有合理決議的資料,所以我需要決議檔案并獲取除 - 符號之外的所有資料。此外,檔案結構不會改變,因此列始終存在(固定)。如您所見,該檔案是銀行相關檔案(交易)。所以有這個“金融機構”,例如我繪制的地圖和其他資料。這個“金融機構”的“結算類別”例如是“MC Acq Fin Detail ATM Out”。決議檔案的最佳方法是什么?
uj5u.com熱心網友回復:
您可以通過使用正則運算式一次決議一行來做到這一點。使用 RegEx 并有一些已知的模式要查找,您可以將當前行的任何內容應用于 RegEx.Match() 呼叫,它將回傳括號組中捕獲的所有部分的串列。這可以防止您不得不繼續進行復雜的 IndexOf() 搜索等。
如果結果回傳預期的段組而不是任何條目,那么您應該很快將這些片段拉出來。定義多個模式應該有助于回圈查看哪個版本具有您正在尋找的背景關系。
可以在執行行內正則運算式示例和測驗運算式以查看它們的作業方式時找到一種這樣的工具來測驗您計劃決議的內容,并且它允許您在描述它正在尋找的內容時進行除錯和單步執行。您可以在代碼中發布我的模式以查看它們的描述方式,并通過從示例檔案中放入一些示例文本進行除錯
StackOverflow 的這個鏈接也有助于在下一個“標記”識別分節符到下一部分之前獲得多個單詞的可能性
這是我為您整理的快速內容。希望對您和其他人來說,它可以幫助識別決議機制與決議和查找所有索引、字串提取、下一個決議等的復雜性。學習如何做模式可能需要時間,但希望我在-line 檔案可幫助您了解它并不像人們想象的那么難。
祝你好運。
private void TryRegParse()
{
if (!File.Exists("TestingRegex.txt"))
return;
// read the text content into already parsed individual lines
var txtLines = File.ReadAllLines("TestingRegex.txt");
// the "*" indicates zero or more spaces before whatever is following it.
var patFinancial = @"^.*?Financial Institution.*?:.*?(?<FinInst>. ?-).*?(?<FinAccnt>.*)";
// Explanation of what I have here for the pattern
// ^ = start of the string
// .*? = zero OR more possible white space/tab charaters
// Financial Institution = find this exact string
// .*?: = there may be zero or more white-space/tab before coming up to the ":" character
// .*? and additional check for zero or more white spaces
// (?<FinInst>. ?-) =
// using the outer (parens) allows Regular expression to pull the extracted portion into a group results
// the ?<FinInst> allows this "group" to be recognized by the name "FinInst" see shortly
// . indicates a single character
// the ?- means keep look ahead from where you are now for UNTIL you get to the - character (whatever appears after the ?)
// This allows you to get multiple possible word(s) / names up to the actual hyphen
// .*?: = another instance there may be zero or more white-space/tab before the final data
// (?<FinAccnt>.*) = parens indicate another group, similarly named like ?<FinInst> above
// create a regular expression object of just this specific pattern
var RegExFinInst = new Regex( patFinancial );
// Now, prepare another string line to parse and its regular expression object to match against.
// for Dates, https://regexland.com/regex-dates/ had a good clarification, but since your dates
// appear in month.day.year format, I had to alter
var patFXSettlement = @"^.*?FX Settlement Date.*?:.*?(?<sMonth>(0[1-9]|1[0-2])).(?<sDay>(0[1-9]|[12][0-9]|3[01])).(?<sYear>\d{4})";
// each pattern, just creating a regular expression of its corresponding pattern to match
var RegSettle= new Regex(patFXSettlement);
// same here on last 2 samples
var patReconFile = @"^.*?Reconciliation File ID.*?:.*?(?<FileId>.*)";
var RegRecon= new Regex(patReconFile);
var patTxnCurr = @"^.*?Transaction Currency.*?:.*?(?<Currency>[A-Z]{3}).*";
var RegTxnCurr = new Regex(patTxnCurr);
// go through each line
foreach ( var s in txtLines )
{
// see if the current line "matches" the Financial Institution pattern
// As you can see from the "named" groups, you can get without having to
// know what ordinal number the group is within the expression, you can get by its name
var hasMatch = RegExFinInst.Match(s);
if( hasMatch.Success )
{
MessageBox.Show("Financial Institution Group: " hasMatch.Groups["FinInst"] "\r\n"
"Account: " hasMatch.Groups["FinAccnt"]);
// done with this line
continue;
}
// if not, try the next, and next and next
hasMatch = RegSettle.Match(s);
if( hasMatch.Success )
{
MessageBox.Show("FX Settlement Month: " hasMatch.Groups["sMonth"]
" Day: " hasMatch.Groups["sDay"]
" Year: " hasMatch.Groups["sYear"] );
// done with this line
continue;
}
hasMatch = RegRecon.Match(s);
if (hasMatch.Success)
{
MessageBox.Show("Reconcilliation File: " hasMatch.Groups["FileId"] );
// done with this line
continue;
}
hasMatch = RegTxnCurr.Match(s);
if (hasMatch.Success)
{
MessageBox.Show("Transaction Currency: " hasMatch.Groups["Currency"]);
// done with this line
continue;
}
}
}
uj5u.com熱心網友回復:
我最終手動決議它。所以正如我所說,結構總是一樣的。我使用快速失敗技術,如果出現問題,我會拋出例外
IRuntimeServices runtimeServices = new RuntimeServices();
List<string> transactionTitles = new();
List<string> transactionDetails = new();
string constText = "Financial Institution";
bool isTitleFinished = false;
int counterTable = 0;
int counterTitle = 0;
for (int i = 0, j = i; i < text.Length; i )
{
if (text[i] == ' ' && !isTitleFinished)
{
Helper.AddItem(transactionTitles, text, j, counterTitle);
isTitleFinished = true;
j = i;
counterTitle = 0;
}
else if(!isTitleFinished && text[i] != ' ')
{
counterTitle ;
}
if (isTitleFinished)
{
if (text.Length >= i constText.Length || text.IsLastIndex(i))
{
if(text.IsLastIndex(i))
{
Helper.AddItem(transactionDetails, text, j,null);
}
else if (text.IsSubStrEqualToSpecificStr(i,constText))
{
Helper.AddItem(transactionDetails, text, j, counterTable);
isTitleFinished = false;
counterTable = 0;
j = i;
}
else
{
counterTable ;
}
}
}
}
ICollection<Transaction> transactions = new List<Transaction>();
for (int i = 0; i < transactionTitles.Count; i )
{
string[] titlePairs = transactionTitles[i]
.Trim()
.Split(new char[] { '\n', '\r' },
StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, string> transactionTitlesDict = new ();
for (int j = 0; j < titlePairs.Length; j )
{
string[] nameAndValue = titlePairs[j].Split(":");
transactionTitlesDict.Add(nameAndValue[0].Trim(), nameAndValue[1].Trim());
}
Transaction transaction = runtimeServices
.CreateCustomObject<Transaction>(transactionTitlesDict);
string[] detailPairs = transactionDetails[i]
.Trim()
.Split(new char[] { '\n', '\r' },
StringSplitOptions.RemoveEmptyEntries);
string[] detailTitlesPart1 = detailPairs[1]
.Trim()
.Split(new char[] { '\n', '\r','!' },
StringSplitOptions.RemoveEmptyEntries);
string[] detailTitlesPart2 = detailPairs[2]
.Trim()
.Split(new char[] { '\n', '\r', '!' },
StringSplitOptions.RemoveEmptyEntries);
IList<string> transactionDetailsTitles = new List<string>();
if(detailTitlesPart1.Length != detailTitlesPart2.Length)
{
throw new Exception("Invalid format");
}
for (int p = 0; p < detailTitlesPart1.Length; p )
{
transactionDetailsTitles
.Add($"{detailTitlesPart1[p].Trim()} {detailTitlesPart2[p].Trim()}");
}
IList<string[]> transactionDetailsData = new List<string[]>();
for (int k = 4; k < detailPairs.Count() - 2; k )
{
string[] data = detailPairs[k]
.Trim()
.Split(new[] { " ","!" },
StringSplitOptions.RemoveEmptyEntries);
transactionDetailsData.Add(data);
}
Dictionary<string, string> transactionDetailsDict = new();
foreach (string[] transactionDetailDataRow in transactionDetailsData)
{
for (int l = 0; l < transactionDetailsTitles.Count; l )
{
if (transactionDetailDataRow.Count() != transactionDetailsTitles.Count)
{
throw new Exception("Invalid format");
}
transactionDetailsDict
.Add(transactionDetailsTitles[l].Trim(), transactionDetailDataRow[l].Trim());
}
// Don't pay attention to this part
SettlementDetail settlementDetail = runtimeServices
.CreateCustomObject<SettlementDetail>(transactionDetailsDict);
transaction.SettlementDetails.Add(settlementDetail);
transactionDetailsDict.Clear();
}
transactions.Add(transaction);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/497982.html
下一篇:子類化`Struct`時添加方法
