从文件中获取文本 C#

3
我正在逐行读取文本文件,并想要在检查是否包含特殊字符的行中获取数据。 在我的情况下,我想要检查该行是否包含 <#Tag()> ,如果包含,则获取 ()之间的字符串,即如果该行包含 <#Tag(param1)> ,则应返回param1

但是问题在于该行可能包含多个 <#Tag()>。 例如,该行如下:<#Tag(value1)> <#Tag(value2)> <#Tag(value3)> 那么它应首先返回 value1,然后是 value2,最后是 value3

string contents = File.ReadAllText(@"D:\Report Format.txt");
int start = contents.IndexOf("Header") + "Header".Length;
int end = contents.IndexOf("Data") - "Header".Length;
int length = end - start;
string headerData = contents.Substring(start, length);
headerData = headerData.Trim(' ', '-');
MessageBox.Show(headerData);
using (StringReader reader = new StringReader(headerData))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        if (line.Contains("<#Tag"))
        {
            string input = line;
            string output = input.Split('<', '>')[1];
            MessageBox.Show(output);
            Globals.Tags.SystemTagDateTime.Read();
            string newoutput =  Globals.Tags.SystemTagDateTime.Value.ToString();
            input = input.Replace(output, newoutput);
            input = Regex.Replace(input, "<", "");
            input = Regex.Replace(input, ">", "");
            MessageBox.Show(input);
        }
    }
}

你尝试过使用正则表达式吗? - tchelidze
2
请耐心等待正则表达式大师出现,并用一行代码完成此任务。 - Adam Houldsworth
如果情况可能比这更复杂,您可能需要考虑使用解析器,而不是尝试使用字符串操作或正则表达式来完成此操作。 - Damien_The_Unbeliever
4个回答

3

请尝试以下操作:

var matches = Regex.Matches(line, @"(?<=\<\#Tag\()\w+(?=\)\>)")
foreach (Match match in matches)
  MessageBox.Show(match.Value);

如果您想实现评论中描述的上下文,请尝试以下操作。
  var line = "<#Tag(value1)> <#Tag(value2)>  <#Tag(value3)>";
  var matches = Regex.Matches(line, @"(?<=\<\#Tag\()\w+(?=\)\>)");
  //use matches in your case to find values. i assume 10, 20 , 30
  var values = new Dictionary<string, int>() { { "value1", 10 }, { "value2", 20 }, { "value3", 30 } };
  const string fullMatchRegexTemplate = @"\<\#Tag\({0}\)\>";
  foreach (var value in values)
    Regex.Replace(line, string.Format(fullMatchRegexTemplate, value.Key), value.Value.ToString());

这似乎可以让你开始,但它只匹配在线正则表达式测试器中的第一个。https://regex101.com/ - Adam Houldsworth
@AdamHouldsworth 请添加全局修饰符。 - tchelidze
1
哇,你看那个,太棒了。 - Adam Houldsworth
value1、value2 和 value3 应该被替换为它们的值。 - Parth Desai
@ParthDesai 我会尝试。 - tchelidze
显示剩余6条评论

0

这可能对你有帮助

[^a-zA-Z0-9]

基本上它匹配所有非字母数字字符。

    private void removeTag()
    {
        string n = "<#Tag(value1)> <#Tag(value2)>  <#Tag(value3)>";
        string tmp = Regex.Replace(n, "Tag+", "");
        tmp = Regex.Replace(tmp, "[^0-9a-zA-Z]+", ",") ;
    }

还有一个可能是

string tmp = Regex.Replace(n, "[^0-9a-zA-Z]*[Tag]*[^0-9a-zA-Z]", ",");

0

你也可以通过按照常量值<#Tag()>对字符串进行分割来收集它们,例如:

string str = "<#Tag(value1)> <#Tag(value2)>  <#Tag(value3)>";
string[] values = str.Split(new string[] { "<#Tag(", ")>" }, StringSplitOptions.RemoveEmptyEntries);

values 包含:

value1, value2, value3

在消息框中显示结果:

foreach (string val in values) {
    if (!(String.IsNullOrEmpty(val.Trim()))) {
        MessageBox.Show(val);
    }
}

根据您的评论进行编辑:

我可以在一个消息框中以与原来相同的间距显示完整的value1 value2 value3吗,而不是使用逗号?

string text = "";
foreach (string val in values) {
    text += val;
}
MessageBox.Show(text);

基于评论: 现在,在将最后一个查询显示在消息框之前,我想用它们的值替换它,例如10、20和30。

string text = "";
foreach (string val in values) {
   // where val is matching your variable (let's assume you are using dictionary for storing the values)
   // else is white space or other... just add to text var.
   if (yourDictionary.ContainsKey(val)) {
       text += yourDictionary[val];
   } else {
       text += val;
   }
}
MessageBox.Show(text);

我想要弹出三个分别为value1,value2和value3的消息框。它是动态的,可能是4个、5个或1个。 - Parth Desai
我添加了代码以在消息框中显示结果。 这将适用于您字符串中的1、3、99等匹配项。 - DDan
现在它也处理空格了。 - DDan
我能否在一个消息框中显示完整的value1 value2 value3,而不是用逗号,而是保持原来的间距? - Parth Desai
现在是最后一个查询,在将其显示在消息框中之前,我想用它们的值替换它,例如10、20和30。 - Parth Desai
让我们在聊天中继续这个讨论 - Parth Desai

0

你可以使用正则表达式来实现这个功能(我会为此工作)- 但是一个简单的快捷方式是:

var tags  = line.Split(new string[] { "<#Tag" }, StringSplitOptions.None);
foreach(var tag in tags)
{
 //现在解析每一个标签
}

我看到tchelidze刚刚发布了一个看起来非常好的正则表达式,所以我将推迟到那个答案作为正则表达式的答案。


它有效,但我也想将其替换为其值,并将其放置在字符串中,与原始空间相同,例如<#Tag(value1)> <#Tag(value2)> <#Tag(value3)>,然后是value1 value2 value3(与<#Tag(value1)> <#Tag(value2)> <#Tag(value3)>相同的空间),然后是它的值10 20 30(与<#Tag(value1)> <#Tag(value2)> <#Tag(value3)>相同的空间)。 - Parth Desai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接