【问题标题】:How to get substring from string containing newlines?如何从包含换行符的字符串中获取子字符串?
【发布时间】:2021-08-23 11:09:22
【问题描述】:

如果响应长度大于指定的长度,我试图从响应字符串中获取子字符串并循环遍历它。我的代码:

string response = //response from API
if (response.Length > 4096)
{
    for (int i = 0; i < response.Length; i += 4096)
    {
        string rplymsg = response.Substring(i, 4095);
        //other code using rplymsg 
    }
}
else
{
    //other code using response 
}

我尝试过String.Substring 方法,它在调试中返回具有指定长度的子字符串,但实际子字符串长度大于。 (我通过在记事本++中粘贴子字符串来验证。)

我认为问题是因为response 字符串和子字符串rplymsg 包含新行\n。 是否有任何解决方案或更好的方法来获取包含换行符的字符串计数,以便我可以根据该长度提取子字符串。

编辑:

例如:

String value = "Hi\nHello.";
int startIndex = 0;
int length = 4;
String substring = value.Substring(startIndex, length);
Console.WriteLine(substring);

// Output:
// Hi
// H

// Expected output:
// Hi\n

【问题讨论】:

  • 为什么你只得到 4095 个字符的子字符串而不是 4096 个?
  • 如果你想从 HTML 中提取数据,那么像 Html Agility Pack 这样的东西可以让你更容易。
  • 您正在 for 循环中创建新字符串。你的逻辑正确吗?如果要从头开始获取子字符串,则必须将 0 作为第一个参数传递。
  • 看起来 notepad++ 为每个换行符计算 2 个字符...在代码长度和 Notepad++ 长度之间有 37 个字符的差异,而 Notepad++ 中总共有 38 行。我认为你应该依赖于你在代码中得到的长度,而不是依赖于编辑器......
  • @phuzi 字符串中的字符个数rplymsg

标签: c# asp.net string for-loop


【解决方案1】:

如果在字符串小于限制大小 4096 的情况下保留换行符,那么我认为您应该在该字符上拆分字符串,但不仅仅是String.Substring(...),还可以考虑使用String.Split(...)处理从它返回的字符串数组。例如:

    string response = "abcd\nefgh\nijklmnop\nrst\n";
    var maxLength = 5;
    var delimiter = new char[]{'\n'};
    var strings = response.Split(delimiter, StringSplitOptions.None); 
      

    foreach(var s in strings)
    {
        var delimited = s + '\n';//add newline as Split removes them from the result
        if(delimited.Length>maxLength)
        {
            var sub = delimited;
            while(sub.Length>maxLength)
            {
               var p = sub.Substring(0, maxLength-1);
               Console.WriteLine($"partial :{p}");
               sub = sub.Remove(0,maxLength-1);
            }
            Console.WriteLine($"end :{sub}");
        }
        else
        {
            Console.WriteLine($"original :{delimited}");
        }
    }

此代码不完全存在,因为它仍会输出额外的消息,但它应该给您一个想法(用您的处理代码替换 Console.WriteLine

【讨论】:

    【解决方案2】:

    你的 Notepad++ 截图给出了解释。

    .Net 中的原始文本仅使用换行符,但您的 Notepad++ 已配置(在右下角)使用 Windows 样式 (CR LF)。这意味着,如果您将一些文本粘贴到该窗口中(这可以通过事实证明,您的文件名为 new 1 并带有红色图标),它将自动转换为当前样式。这意味着 Notepad++ 在每个 LF 之前添加了一个 CR 并增加了文本的长度。

    您是否会将 .Net 中的文本写入文件并使用 Notepad++ 打开该文件,您会看到真实的长度。所以错误不在 .Net 或 Visual Studio 中。您假设在 Notepad++ 中看到的内容与在 Visual Studio 中相同。

    要解决此问题,请在 Windows 样式的 Notepad++ 右下角单击鼠标右键并选择 UNIX。 Notepad++ 将转换文件,您应该会看到与 Visual Studio 中相同的长度(除非原始文本混合了 Windows 和 Unix 样式)。

    关于最后一个例子的更新

    该示例完全按预期工作。你有这个测试字符串Hi\nHello.

    如果从中取出 4 个字符,则得到 HiLFH。当你将这四个字符打印到控制台时,它会打印出来

    Hi
    H
    

    代码中的反斜杠是一个转义字符,它告诉 .Net 下一个字符不是普通的 n。相反,它应该是单个字符的换行符。取而代之的是,您还可以测试Hi\tHello。这意味着在两个词之间放置一个制表符。

    因此,您始终必须真正关心给定文本的可视化方式。如果您在 Visual Studio 的监视窗口中查看字符串变量,您会看到类似 Hi\nHello 的内容来可视化空白字符,但如果您单击间谍玻璃,您会看到没有 \n 的文本,但有一条实线 -休息。

    【讨论】:

    • 你能帮我完成我编辑的例子吗?
    • @HarshadRaval 更新了我的答案。
    • 我正在其他地方处理该子字符串,他们将 Hi\nHello 视为 9 个字符。如何处理?
    • 那么问题来了,他们在他们的代码中是什么?
    猜你喜欢
    • 2017-10-19
    • 2020-04-05
    • 2020-08-26
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 2019-04-18
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多