【问题标题】:C# insert string in multiline stringC#在多行字符串中插入字符串
【发布时间】:2011-10-19 18:06:46
【问题描述】:

我有一个多行字符串(来自使用 ReadAllText 的 txt 文件)。 字符串如下所示:

R;0035709310000026542510X0715;;;  
R;0035709310000045094410P1245;;;  
R;0035709310000026502910Z1153;;;

我想输入一个“;”在位置 22 的每一行中,所以它看起来像这样:

R;00357093100000265425;10X0715;;;  
R;00357093100000450944;10P1245;;;  
R;00357093100000265029;10Z1153;;;

多行字符串始终包含相同数量的数据,但并不总是 3 行 - 有时更多行。

我怎么做这个?请显示一些代码。

非常感谢 :-) 最好的祝福 弯曲

【问题讨论】:

标签: c# multilinestring


【解决方案1】:

试试这个...

using System.IO;
using System.Linq;

var lines = File.ReadAllLines("data.txt");
var results = lines.Select(x => x.Insert(22, ";"));

【讨论】:

  • 这确实需要两倍的内存。这里不是问题(OP 提到“超过 3 行”),但我不建议将它用于 Gigabyte 数据。
  • @Henk - 因为我没有对原始数据进行操作,基本上是在复制它?
  • 是的,你会在整个过程中阻止整个数组的 GC。
【解决方案2】:

第 1 步,不要使用 ReadAllText()。请改用 ReadAllLines()。

 string[] myLinesArray = File.ReadAllLines(...);

第 2 步,将所有行(字符串)替换为更改后的版本。

for(int i = 0; i < myLinesArray.Length; i++)
    myLinesArray[i] = myLinesArray[i].Insert(22, ";");

第 3 步,使用 WriteAllLines()

【讨论】:

  • 谢谢 Henk - 它有效 :-) 并感谢您的快速响应
【解决方案3】:

试试这个

string s ="R;0035709310000026542510X0715;;;";
s = s.Insert(22,";");
Console.Write(s);

或使用正则表达式

    string s =@"R;0035709310000026542510X0715;;;
R;0035709310000045094410P1245;;;
R;0035709310000026502910Z1153;;;";
    string resultString = Regex.Replace(s, "^.{22}", "$0;", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    Console.Write(resultString);

【讨论】:

    【解决方案4】:

    我认为最好是逐行读取源文件并修改该行。

    您可以在 StringBuilder 中构建新文件,或者,如果文件很大, 将其写入新文件,用于最后替换源。

    类似的,

    using System.IO;
    
    string tempFileName = Path.GetTempFileName();
    
    using (StreamWriter target = File.CreateText(tempFileName))
    {
        using(StreamReader source = file.OpenText("YourSourceFile.???"))
        {
            while (source.Peek() >= 0)
            {
                target.WriteLine(source.ReadLine().Insert(22, ";"));
            }
        }
    }
    
    File.Delete("YourSourceFile.???");
    File.Move(tempFileName, "YourSourceFile.???");
    

    这种方法变得特别适用于大文件,因为它避免了一次将所有数据加载到内存中,但是对于除了非常大的文件之外的所有文件,或者我猜,如果行非常(非常)长,性能会很好。

    【讨论】:

    • 是的,对于非常大的文件,这将是唯一的选择。但请注意,OP 提到“超过 3 行”。在 Fx4+ 中,您可以为此使用 File.GetLines()。
    • @Henk Holterman,考虑到超过 3 行的所有可能文件的集合变得很哲学,因为集合没有上限,所以“大”文件“比”小文件无限多。但是,我愿意承认,现实世界中的文件集可能更偏重于“小”方面,所以我想这一点没有实际意义,只有 OP 可以说。 File.GetLines() 在下一个 .Net 版本中,使用yield return 为我们提供IEnumerable&lt;string&gt; 的函数会很有用,我可以用StreamReader 编写自己的扩展。
    • 不是哲学,只是球场。
    • 我永远无法确定我手指的哪一边是干的 :-)
    【解决方案5】:

    按照建议,您可以使用Insert 方法来实现您的目标。

    如果您的文件包含很多行并且您需要一次处理 1 行,您也可以考虑从 TextReader 逐行读取它。

    【讨论】:

    • 效果和我的建议一样。
    【解决方案6】:

    您可以使用正则表达式:

    myString = Regex.Replace(myString, @"(^.{22})", @"\1;", RegexOptions.Multiline);
    

    说明: 你有 3 个字符串参数:

    • 第一个是输入
    • 第二个是模式
    • 第三个是替换字符串

    在模式中:

    • () 是一个捕获组:您可以在替换字符串中使用 \n 调用它,n 是模式中捕获组的从 1 开始的索引。在这种情况下,\1 是任何匹配的 "(^.{22})"
    • “^”是一行的开头(因为我们设置了多行选项,否则就是输入字符串的开头)
    • “。”匹配任何字符
    • {22} 表示您想要前面的模式(在本例中为“.”,任何字符)22 次​​li>

    所以这意味着: "在任何包含 22 个或更多字符的行中,将前 22 个字符替换为相同的 22 个字符加上“;”

    【讨论】:

    • 你不觉得有点(过度)复杂吗?当req 说Insert 时,寻找一个Insert() 方法。当 req 谈论模式时,请使用 RegEx。
    • 是的,也许这是矫枉过正。您必须比较性能,但我认为由于正则表达式在第一次使用时由 CLR 在内部编译,如果您要多次运行代码,正则表达式可能会更快。
    • 不仅仅是性能。我在考虑可读性。有关性能,请参阅@jodrel 的答案。
    • 性能还可以,实际上读取文件将是最重要的时间消费者。但我不认为可读性是一个问题,模式很简单,如果有人不习惯正则表达式,这是一个好的开始。无论如何,当我看到 ReadAllLines 解决方案时,它对我来说似乎也更好。我会加的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多