![](/img/trans.png)
[英]c# Read a text file until a specific word and copy lines in a new text file
[英]C# - Read/Copy/Replace Lines In Text
我有一个要打开的文本文件,它的格式与此类似:
10 SOME TEXT
20 T A40
B B5, C45, D48
30 B E25
40 B F17, G18
60 T H20, I23,
B J6, K7, L8, M9, N10, O11, P12,
Q31, R32, S33, T34, U35, V36,
W37, X38, Y39
100 T Z65
360 B A1, B4, C5, D6, E7, F10
2000 T SOME TEXT
423 TEXT
有了这个文本,我需要能够阅读它并相应地替换值。 如果 ReadLine 以数字开头(即 10、20、30、40、60、100、360、2000、423),我需要检查其后是否有 T、B 或文本。 唯一需要更改/重新格式化这些行的情况,以及 output 不同。
示例:10 很好,除了我想在每个数字前面添加零以使它们长 4 位(即,10 转为 0010,360 转为 0360,2000 保持不变)。 当读取字符串“B B5,C45,D48”时(这是文本中的第三行),我需要将其更改为“20A B5,C45,D48”。 我需要抓住“B”上方的数字并将其连接到“B”并将“B”替换为“A”。 如果不是“B”而是“T”,我只需要删除“T”。 此外,如果一行不以数字或“B”开头(即 Q31 或 W37),我需要将该行与前一行连接起来。
因此,在更改发生后,它应该如下所示:
0010 SOME TEXT
0020 A40
0020A B5, C45, D48
0030A E25
0040A F17, G18
0060 H20, I23,
0060A J6, K7, L8, M9, N10, O11, P12, Q31, R32, S33, T34, U35, V36, W37, X38, Y39
0100 Z65
0360A A1, B4, C5, D6, E7, F10
2000 SOME TEXT
0423 TEXT
我目前正在尝试使用 Regex 来执行此操作,但有人告诉我有一种更简单的方法可以执行此操作,但我不确定如何操作。 到目前为止,我已经能够在数字前面添加零。 此外,我的代码在所有内容的末尾添加了一个“A”,并将原始数字保留在下一行,并且我没有抓取除数字以外的任何内容的行。
这就是我当前的 output 的样子:
0010A
0010
0020A
0020
0030A
0030
0060A
0060
0100A
0100
0360A
0360
2000
2000
0423A
0423
我显然在使用正则表达式做错了什么。
这是我当前的代码:
private void openRefsButton_Click(object sender, EventArgs e)
{
// Initialize the OpenFileDialog to specify the .txt extension as well as
// its intial directory for the file.
openRefs.DefaultExt = "*.txt";
openRefs.Filter = ".txt Files|*.txt";
openRefs.InitialDirectory = "C:\\";
openRefs.RestoreDirectory = true;
try
{
// Open the contents of the file into the originalTextRichTextBox.
if (openRefs.ShowDialog() == DialogResult.OK && openRefs.FileName.Length > 0)
refsTextRichTextBox.LoadFile(openRefs.FileName, RichTextBoxStreamType.PlainText);
// Throws a FileNotFoundException otherwise.
else
throw new FileNotFoundException();
StreamReader refsInput = File.OpenText(openRefs.FileName);
string regExpression = @"^[\d]+";
string findNewBottomRegex = @"^B\s";
StringBuilder buildNumberText = new StringBuilder();
StringBuilder formatMatchText = new StringBuilder();
foreach (string allLines in File.ReadAllLines(openRefs.FileName))
{
Match newBottomMatch = Regex.Match(allLines, findNewBottomRegex);
Match numberStartMatch = Regex.Match(allLines, regExpression);
int counter = 0;
if (counter < numberStartMatch.Length)
{
if (numberStartMatch.Value.Length == 2)
{
if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
{
finalTextRichTextBox.AppendText("00" + numberStartMatch + "A\n");
}
finalTextRichTextBox.AppendText("00" + numberStartMatch + "\n");
}
else if (numberStartMatch.Value.Length == 3)
{
if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
{
finalTextRichTextBox.AppendText("0" + numberStartMatch + "A\n");
}
finalTextRichTextBox.AppendText("0" + numberStartMatch + "\n");
}
else
{
if (refsTextRichTextBox.Text.Contains(newBottomMatch.ToString()))
{
finalTextRichTextBox.AppendText(numberStartMatch + "A\n");
}
finalTextRichTextBox.AppendText(numberStartMatch + "\n");
}
counter++;
}
}
}
// Catches an exception if the file was not opened.
catch (Exception)
{
MessageBox.Show("There was not a specified file path.", "Path Not Found Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
问题):
工作流程@jaywayco
这是一个非常蹩脚的程序解决方案:
using System.IO;
using System.Collections.Generic;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var list = new List<string>();
using (var reader = File.OpenText(@"c:\input.txt"))
{
while (true)
{
var line = reader.ReadLine();
if (string.IsNullOrEmpty(line)) break;
list.Add(line);
}
}
list = HandleRemoveTRequirement(list);
list = HandleFourDigitRequirement(list);
list = HandleConcatRequirement(list);
list = HandleStartsWithBRequirement(list);
list = HandleSecondElementIsBRequirement(list);
using (var output = new StreamWriter(@"c:\output.txt"))
{
foreach (var line in list)
{
output.WriteLine(line);
}
}
}
static List<string> HandleSecondElementIsBRequirement(List<string> list)
{
var result = new List<string>();
foreach (var line in list)
{
var parts = line.Split(' ');
if (parts[1].Equals("B"))
{
parts[0] += "A";
parts[1] = string.Empty;
result.Add(string.Join(" ", parts).Replace(" ", " "));
}
else
{
result.Add(line);
}
}
return result;
}
static List<string> HandleStartsWithBRequirement(List<string> list)
{
var result = new List<string>();
var i = 0;
foreach (var line in list)
{
var parts = line.Split(' ');
if (parts[0].Equals("B"))
{
parts[0] = string.Empty;
result.Add(list[i - 1].Split(' ')[0] + "A" + string.Join(" ", parts));
}
else
{
result.Add(line);
}
i++;
}
return result;
}
static List<string> HandleConcatRequirement(List<string> list)
{
var result = new List<string>();
foreach (var line in list)
{
var parts = line.Split(' ');
int test;
if (int.TryParse(parts[0], out test) || parts[0].Equals("B"))
{
result.Add(line);
}
else
{
result[result.Count -1] += line;
}
}
return result;
}
static List<string> HandleRemoveTRequirement(List<string> list)
{
var result = new List<string>();
foreach (var line in list)
{
var parts = line.Split(' ');
if (parts[1].Equals("T"))
{
parts[1] = string.Empty;
}
result.Add(string.Join(" ", parts).Replace(" ", " "));
}
return result;
}
static List<string> HandleFourDigitRequirement(List<string> list)
{
var result = new List<string>();
foreach (var line in list)
{
var parts = line.Split(' ');
int test;
if (int.TryParse(parts[0], out test))
{
parts[0] = parts[0].PadLeft(4, '0');
result.Add(string.Join(" ", parts));
}
else
{
result.Add(line);
}
}
return result;
}
}
}
这些是相当复杂的要求,我很想将其作为工作流来实现。 通过这种方式,您可以分离出每个逻辑步骤,这将提高可维护性。
我很想将文本文件表示为字符串数组 arrays 甚至数据表。 然后您可以编写连接/转换特定值的通用函数
一种可能解决此问题的方法类似于 jaywayco 的方法。
我首先将由空格分隔的每一行放入它自己的数组中。 将该数组放入 arrays 数组中。 从那里您可以考虑您的工作流程。 您的线阵列由空格分隔,您可以根据第一个值(数字或字母 B 等)确定如何打印它...如果是 B,您知道它应该以 array[i-1] 开头第一个值,这将是数字等。您必须稍微考虑一下逻辑,但我认为您可以理解我来自哪里。 我不确定这是否是最好的方法,但我认为这是我解决它的方法。 祝你好运!
编辑:这是一些模拟代码...
var mainArray = new Array[textFile.Count];
//obviously get the count of number of lines set that to the size of your array object.
for(int i=0; i < mainArray.Length; i++)
{
var line = methodToGetLineFromTextFile[i];
string[] lineArray = line.Split(' ');
mainArray[i] = lineArray;
}
//Once you have everything loaded into your arrays, apply your workflow logic.
希望这可以帮助!
我会 go 关于此任务的方式是根据您的要求编写一组单元测试,然后让它们一次通过一个(每个要求有一个测试)。
正如 jaywayco 建议的那样,我会将文件读入一个行数组,然后将您的每个规则实现为可以单独测试的行转换方法。 我可能会分离出 select 可以应用哪些转换的方法。 然后遍历线条并应用转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.