Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#/.NET中强制CRLF的快速方法是什么?_C#_.net_String_Newline - Fatal编程技术网

在C#/.NET中强制CRLF的快速方法是什么?

在C#/.NET中强制CRLF的快速方法是什么?,c#,.net,string,newline,C#,.net,String,Newline,如何将字符串中的所有新行序列规范化为一种类型 我正在寻找使他们所有的电子邮件(MIME文件)的目的CRLF。理想情况下,这将被包装在一个静态方法中,执行速度非常快,并且不使用正则表达式(因为换行符、回车符等的方差是有限的)。也许有一种BCL方法我忽略了 假设:在仔细考虑之后,我认为可以安全地假设CR是独立的或是CRLF序列的一部分。也就是说,如果您看到CRLF,那么您知道所有CR都可以删除。否则,很难判断像“\r\n\n\r”这样的内容应该有多少行 如果输入仅包含一种类型的换行符(CR、LF或C

如何将字符串中的所有新行序列规范化为一种类型

我正在寻找使他们所有的电子邮件(MIME文件)的目的CRLF。理想情况下,这将被包装在一个静态方法中,执行速度非常快,并且不使用正则表达式(因为换行符、回车符等的方差是有限的)。也许有一种BCL方法我忽略了

假设:在仔细考虑之后,我认为可以安全地假设CR是独立的或是CRLF序列的一部分。也就是说,如果您看到CRLF,那么您知道所有CR都可以删除。否则,很难判断像“\r\n\n\r”这样的内容应该有多少行

如果输入仅包含一种类型的换行符(CR、LF或CR+LF),则这将起作用。

这取决于具体的要求。特别是,您希望如何单独处理“\r”?这算不算断线?例如,“a\n\rb”应该如何处理?是一个非常奇怪的换行符,一个“\n”换行符,然后是一个流氓“\r”,还是两个单独的换行符?如果“\r”和“\n”都可以单独作为换行符,为什么“\r\n”不应被视为两个换行符

下面是一些我认为相当有效的代码

using System;
using System.Text;

class LineBreaks
{    
    static void Main()
    {
        Test("a\nb");
        Test("a\nb\r\nc");
        Test("a\r\nb\r\nc");
        Test("a\rb\nc");
        Test("a\r");
        Test("a\n");
        Test("a\r\n");
    }

    static void Test(string input)
    {
        string normalized = NormalizeLineBreaks(input);
        string debug = normalized.Replace("\r", "\\r")
                                 .Replace("\n", "\\n");
        Console.WriteLine(debug);
    }

    static string NormalizeLineBreaks(string input)
    {
        // Allow 10% as a rough guess of how much the string may grow.
        // If we're wrong we'll either waste space or have extra copies -
        // it will still work
        StringBuilder builder = new StringBuilder((int) (input.Length * 1.1));

        bool lastWasCR = false;

        foreach (char c in input)
        {
            if (lastWasCR)
            {
                lastWasCR = false;
                if (c == '\n')
                {
                    continue; // Already written \r\n
                }
            }
            switch (c)
            {
                case '\r':
                    builder.Append("\r\n");
                    lastWasCR = true;
                    break;
                case '\n':
                    builder.Append("\r\n");
                    break;
                default:
                    builder.Append(c);
                    break;
            }
        }
        return builder.ToString();
    }
}
public static string NormalizeNewLine(this string val)
{
    if (string.IsNullOrEmpty(val))
        return val;

    const int page = 6;
    int a = page;
    int j = 0;
    int len = val.Length;
    char[] res = new char[len];

    for (int i = 0; i < len; i++)
    {
        char ch = val[i];

        if (ch == '\r')
        {
            int ni = i + 1;
            if (ni < len && val[ni] == '\n')
            {
                res[j++] = '\r';
                res[j++] = '\n';
                i++;
            }
            else
            {
                if (a == page) // Ensure capacity
                {
                    char[] nres = new char[res.Length + page];
                    Array.Copy(res, 0, nres, 0, res.Length);
                    res = nres;
                    a = 0;
                }

                res[j++] = '\r';
                res[j++] = '\n';
                a++;
            }
        }
        else if (ch == '\n')
        {
            int ni = i + 1;
            if (ni < len && val[ni] == '\r')
            {
                res[j++] = '\r';
                res[j++] = '\n';
                i++;
            }
            else
            {
                if (a == page) // Ensure capacity
                {
                    char[] nres = new char[res.Length + page];
                    Array.Copy(res, 0, nres, 0, res.Length);
                    res = nres;
                    a = 0;
                }

                res[j++] = '\r';
                res[j++] = '\n';
                a++;
            }
        }
        else
        {
            res[j++] = ch;
        }
    }

    return new string(res, 0, j);
}
简单变体:

Regex.Replace(input, @"\r\n|\r|\n", "\r\n")
为了获得更好的性能:

static Regex newline_pattern = new Regex(@"\r\n|\r|\n", RegexOptions.Compiled);
[...]
    newline_pattern.Replace(input, "\r\n");

我是说,这是一个快速的方法

它不使用昂贵的正则表达式函数。 它也不使用多个替换函数,每个替换函数都通过多次检查、分配等对数据进行循环

因此,直接在一个
循环中对
进行搜索。对于必须增加结果数组容量的次数,在
array.Copy
函数中还使用了一个循环。这就是所有的循环。 在某些情况下,较大的页面大小可能更有效

using System;
using System.Text;

class LineBreaks
{    
    static void Main()
    {
        Test("a\nb");
        Test("a\nb\r\nc");
        Test("a\r\nb\r\nc");
        Test("a\rb\nc");
        Test("a\r");
        Test("a\n");
        Test("a\r\n");
    }

    static void Test(string input)
    {
        string normalized = NormalizeLineBreaks(input);
        string debug = normalized.Replace("\r", "\\r")
                                 .Replace("\n", "\\n");
        Console.WriteLine(debug);
    }

    static string NormalizeLineBreaks(string input)
    {
        // Allow 10% as a rough guess of how much the string may grow.
        // If we're wrong we'll either waste space or have extra copies -
        // it will still work
        StringBuilder builder = new StringBuilder((int) (input.Length * 1.1));

        bool lastWasCR = false;

        foreach (char c in input)
        {
            if (lastWasCR)
            {
                lastWasCR = false;
                if (c == '\n')
                {
                    continue; // Already written \r\n
                }
            }
            switch (c)
            {
                case '\r':
                    builder.Append("\r\n");
                    lastWasCR = true;
                    break;
                case '\n':
                    builder.Append("\r\n");
                    break;
                default:
                    builder.Append(c);
                    break;
            }
        }
        return builder.ToString();
    }
}
public static string NormalizeNewLine(this string val)
{
    if (string.IsNullOrEmpty(val))
        return val;

    const int page = 6;
    int a = page;
    int j = 0;
    int len = val.Length;
    char[] res = new char[len];

    for (int i = 0; i < len; i++)
    {
        char ch = val[i];

        if (ch == '\r')
        {
            int ni = i + 1;
            if (ni < len && val[ni] == '\n')
            {
                res[j++] = '\r';
                res[j++] = '\n';
                i++;
            }
            else
            {
                if (a == page) // Ensure capacity
                {
                    char[] nres = new char[res.Length + page];
                    Array.Copy(res, 0, nres, 0, res.Length);
                    res = nres;
                    a = 0;
                }

                res[j++] = '\r';
                res[j++] = '\n';
                a++;
            }
        }
        else if (ch == '\n')
        {
            int ni = i + 1;
            if (ni < len && val[ni] == '\r')
            {
                res[j++] = '\r';
                res[j++] = '\n';
                i++;
            }
            else
            {
                if (a == page) // Ensure capacity
                {
                    char[] nres = new char[res.Length + page];
                    Array.Copy(res, 0, nres, 0, res.Length);
                    res = nres;
                    a = 0;
                }

                res[j++] = '\r';
                res[j++] = '\n';
                a++;
            }
        }
        else
        {
            res[j++] = ch;
        }
    }

    return new string(res, 0, j);
}
公共静态字符串NormalizeNewLine(此字符串val)
{
if(string.IsNullOrEmpty(val))
返回val;
常量int page=6;
INTA=页面;
int j=0;
int len=值长度;
char[]res=新字符[len];
对于(int i=0;i
我现在知道“\n\r”实际上没有在基本平台上使用。但是谁会连续使用两种类型的换行符来表示两种换行符呢

如果您想知道这一点,则需要先看一看,以了解\n和\r两者是否在同一文档中分别使用。

Environment.NewLine


对于非Unix平台,包含“\r\n”的字符串;对于Unix平台,包含“\n”的字符串。

此示例生成四个换行符,而非规范化字符串包含两个换行符。确实,它提出了一个很好的问题,即何时使用序列以及何时删除(忽略)序列。非常酷;这对更随意的输入肯定有用!就我的情况而言,我选择了一个假设(做了一个编辑),但不管怎样,我还是投了赞成票。对。如果性能真的很重要,您可能希望将此解决方案与公认的解决方案进行基准测试,但前提是您已经通过探查器确定了它的重要性!我希望这会更快,因为它只需要对数据进行一次单一的传递?表现不好@是的,这是另一种选择。@JonSkeet这些“测试”很容易阅读,也很容易复制到编辑器或IDE中进行实验。不需要x-u-ms-test等等。正如我们(即我)所希望的那样。也可以通过使用最后一个替换插入BR标记在HTML页面上显示未知文本。Server.HtmlEncode(输入)。替换(“\r\n”、“\n”)。替换(“\r”、“\n”)。替换(“\n”、“
”);这将解决T4模板的问题。我在生成的输出中不断得到疯狂的返回。这是不可读的,我怀疑性能的提高能否弥补它。代码基于stringbuilder替换函数。来源:为什么要回滚编辑?不需要更多的空间,这取决于字符串的大小以及它的性能。使用String.Replace()的所有其他答案都会生成多个字符串,这些字符串可能非常庞大,并且会进行多次传递。最好的解决方案是
myStr=Regex.Replace(myStr,”(?)?