regex 删除多行文本C#

ee7vknir  于 2023-05-08  发布在  C#
关注(0)|答案(4)|浏览(201)

我可能标题不正确,但我有一个多行的文件结构如下:

#### ID: 0 NAME: card_inventory ####
{ ALL CONTENT WOULD GO BETWEEN HERE }
#### ENDCARD ####

#### ID: 1 NAME: card_inventory ####
{ ALL CONTENT WOULD GO BETWEEN HERE }
{ I WANT TO REMOVE ALL REFERENCES TO
  THIS CARD WITH AN ID OF 1 }
#### ENDCARD ####

所以基本上我的问题是我如何找到卡ID和删除它的内容?我在想也许RegEX,但我不确定,因为我从来没有尝试过这种事情。
====更新====
所以我有这个工作,但我有一个新的问题,当我调用我的删除操作

using (StreamWriter sw = File.AppendText(this.cardinfo_path))
{
    sw.WriteLine(Regex.Replace(this.cardinfo_path,
        @"####\sID:\s(" + id + @")\s.*?####\sENDCARD\s####", "TACO",
        RegexOptions.Singleline));
}

它只是将文件名添加到文件的末尾。我哪里做错了?我觉得自己像个新手一样问这个问题。

slhcrj9b

slhcrj9b1#

正则表达式可能不是理想的解决方案,但如果数据结构清晰,那么它就可以工作

####\sID:\s(1)\s.*?####\sENDCARD\s####

(1)替换为要删除的ID。

Regex.Replace( filecontents, 
               @"####\sID:\s(" + cardid + @")\s.*?####\sENDCARD\s####",
               "",
               RegexOptions.Singeline );

这个正则表达式的关键是使用non-greedy.*?匹配,这样它就可以匹配id后面第一个出现的ENDCARD。

0sgqnhkj

0sgqnhkj2#

我将通过一个阅读文件的循环来完成此操作,在检测到“#### ID:1”(并在下次检测到“####”时重置),如果布尔标志为真,则另一个流写入输出文件。
代码看起来大致像(手写):

var reader = new FileReader ("input.cards");
var writer = new FileWriter ("filtered.cards");

var writeToOutput = true;

while (! reader.EndOfStream)
{
    var inputLine = reader.ReadLine ();

    if (inputLine.StartsWith ("####"))
    {
        // control line
        if (inputLine.Contains ("ID: 1"))
            writeToOutput = false;

        if (! writeToOutput && inputLine.Contains ("ENDCARD"))
            writeToOutput = true;
    }

    if (writeToOutput)
        writer.WriteLine (inputLine);
}
m4pnthwp

m4pnthwp3#

也许它可以用一个正则表达式来完成,但是一个小过滤器也可以完成(如果你想做更多的事情,也会给你更多的灵活性):

bool skipCurrentCart = false;

var cartFileName = "yourcartfile";
var tmpFileName = Path.GetTempFileName();

using (var reader = new StreamReader(cartFileName))
using (var writer = new StreamWriter(tmpFileName))
{
    while (!reader.EndOfStream)
    {
         var line = reader.ReadLine();

         if (!skipCurrentCart)
         {
             writer.WriteLine(line);
         }

         if (line.StartsWith(string.Format("#### ID: {0} NAME: card_inventory ####", cartIdToIgnore)))
         {
             skipCurrentCart = true;
         }
         else if (line.StartsWith("#### ENDCARD ####"))
         {
             skipCurrentCart = false;
         }
    }
}

// replace cart file
File.Move(tmpFileName, cartFileName);
tsm1rwdh

tsm1rwdh4#

我被你的问题弄糊涂了。你似乎想要不同的东西。您要删除卡还是只删除其中的内容。以下操作将仅删除其内容。
(?<=(#### ID: 1 NAME: card_inventory ####))(.|\n)+?(?=(#### ENDCARD ####))
只要把卡ID改成你需要的就行了。
或许:
"(?<=(#### ID: " + cardId + " NAME: card_inventory ####))(.|\n)+?(?=(#### ENDCARD ####))"
这将只获取中间的数据,不包括####内容。

相关问题