English 中文(简体)
将体力分解为<>的最佳方法
原标题:Best way to split string into lines
  • 时间:2009-10-02 07:49:04
  •  标签:

你们如何将多线划分成线?

我知道这种方式。

var result = input.Split("

".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

视而不见,失去空线。 是否有更好的解决办法?

最佳回答
  • 如果看上去的话,就只是删除了“ToCharArray的不必要密码。

  • If you want to split by either or , you ve got two options:

    • Use an array literal – but this will give you empty lines for Windows-style line endings :

      var result = text.Split(new [] {  
       ,  
        });
      
    • Bart指出,使用定期表述:

      var result = Regex.Split(text, "
      |
      |
      ");
      
  • 如果你想要保留空线,那么你为什么明确地告诉C#,将他们赶走? (String SplitOptions para amount) - use String SplitOptions. 无

问题回答
using (StringReader sr = new StringReader(text)) {
    string line;
    while ((line = sr.ReadLine()) != null) {
        // do something
    }
}

Update: See here for an alternative/async solution.


这一工作非常出色,比雷克快:

input.Split(new[] {"
", "
", "
"}, StringSplitOptions.None)

It is important to have " " first in the array so that it s taken as one line break. The above gives the same results as either of these Regex solutions:

Regex.Split(input, "
|
|
")

Regex.Split(input, "
?
|
")

除此以外,雷克斯岛的增长率大约为10倍。 我在此检验:

Action<Action> measure = (Action func) => {
    var start = DateTime.Now;
    for (int i = 0; i < 100000; i++) {
        func();
    }
    var duration = DateTime.Now - start;
    Console.WriteLine(duration);
};

var input = "";
for (int i = 0; i < 100; i++)
{
    input += "1 
2
3
4

5 

 6
7
 8
";
}

measure(() =>
    input.Split(new[] {"
", "
", "
"}, StringSplitOptions.None)
);

measure(() =>
    Regex.Split(input, "
|
|
")
);

measure(() =>
    Regex.Split(input, "
?
|
")
);

<<>Output>:

00:00:03.8527616

00:00:31.8017726

00:00:32.5557128

页: 1

public static class StringExtensionMethods
{
    public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
    {
        return str.Split(new[] { "
", "
", "
" },
            removeEmptyLines ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None);
    }
}

<><>Usage:

input.GetLines()      // keeps empty lines

input.GetLines(true)  // removes empty lines

您可使用Regex。 内容:

string[] tokens = Regex.Split(input, @"
?
|
");

Edit: 添加<>>>,以核算(原)麦克风终点站。

如果你想要保持空洞的界线,就只能去掉“强谋”。

var result = input.Split(System.Environment.NewLine.ToCharArray());
string[] lines = input.Split(new[] {  
 ,  
  }, StringSplitOptions.RemoveEmptyEntries);

我有,但根据Jack s answer,s>大大加快了,因为的工作进度不错,虽然稍慢。

public static class StringExtensionMethods
{
    public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
    {
        using (var sr = new StringReader(str))
        {
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                if (removeEmptyLines && String.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                yield return line;
            }
        }
    }
}

<><>Usage:

input.GetLines()      // keeps empty lines

input.GetLines(true)  // removes empty lines

<>试验:

Action<Action> measure = (Action func) =>
{
    var start = DateTime.Now;
    for (int i = 0; i < 100000; i++)
    {
        func();
    }
    var duration = DateTime.Now - start;
    Console.WriteLine(duration);
};

var input = "";
for (int i = 0; i < 100; i++)
{
    input += "1 
2
3
4

5 

 6
7
 8
";
}

measure(() =>
    input.Split(new[] { "
", "
", "
" }, StringSplitOptions.None)
);

measure(() =>
    input.GetLines()
);

measure(() =>
    input.GetLines().ToList()
);

<<>Output>:

00:03.9603894

00:00.0029996

00:04.8221971

略微扭曲了,但一个导管组这样做:

public static IEnumerable<string> Lines(this string Text)
{
    int cIndex = 0;
    int nIndex;
    while ((nIndex = Text.IndexOf(Environment.NewLine, cIndex + 1)) != -1)
    {
        int sIndex = (cIndex == 0 ? 0 : cIndex + 1);
        yield return Text.Substring(sIndex, nIndex - sIndex);
        cIndex = nIndex;
    }
    yield return Text.Substring(cIndex + 1);
}

之后,你可以呼吁:

var result = input.Lines().ToArray();
    private string[] GetLines(string text)
    {

        List<string> lines = new List<string>();
        using (MemoryStream ms = new MemoryStream())
        {
            StreamWriter sw = new StreamWriter(ms);
            sw.Write(text);
            sw.Flush();

            ms.Position = 0;

            string line;

            using (StreamReader sr = new StreamReader(ms))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    lines.Add(line);
                }
            }
            sw.Close();
        }



        return lines.ToArray();
    }

It s tricky to handle mixed line endings properly. As we know, the line termination characters can be "Line Feed" (ASCII 10, , x0A, u000A), "Carriage Return" (ASCII 13, , x0D, u000D), or some combination of them. Going back to DOS, Windows uses the two-character sequence CR-LF u000Du000A, so this combination should only emit a single line. Unix uses a single u000A, and very old Macs used a single u000D character. The standard way to treat arbitrary mixtures of these characters within a single text file is as follows:

  • each and every CR or LF character should skip to the next line EXCEPT...
  • ...if a CR is immediately followed by LF (u000Du000A) then these two together skip just one line.
  • String.Empty is the only input that returns no lines (any character entails at least one line)
  • The last line must be returned even if it has neither CR nor LF.

上一条规则描述了StringReader.ReadLine和相关功能,以下功能产生相同的结果。 这是一个高效的“C#细线突破功能,可随意执行这些准则,正确处理CR/LF的任何任意顺序或组合。 所列举的界线不含任何CR/LF特性。 保留并退回到<代码>。 就业:

/// <summary>
/// Enumerates the text lines from the string.
///   ⁃ Mixed CR-LF scenarios are handled correctly
///   ⁃ String.Empty is returned for each empty line
///   ⁃ No returned string ever contains CR or LF
/// </summary>
public static IEnumerable<String> Lines(this String s)
{
    int j = 0, c, i;
    char ch;
    if ((c = s.Length) > 0)
        do
        {
            for (i = j; (ch = s[j]) !=  
  && ch !=  
  && ++j < c;)
                ;

            yield return s.Substring(i, j - i);
        }
        while (++j < c && (ch !=  
  || s[j] !=  
  || ++j < c));
}

注:如果你不考虑设立<代码>StringReader的间接费用,则你可使用以下C# 7代码。 如前所述,虽然上述例子可能略有提高,但这两项职能都产生了同样的结果。

public static IEnumerable<String> Lines(this String s)
{
    using (var tr = new StringReader(s))
        while (tr.ReadLine() is String L)
            yield return L;
}

划线,不作任何分配。

public static LineEnumerator GetLines(this string text) {
    return new LineEnumerator( text.AsSpan() );
}

internal ref struct LineEnumerator {

    private ReadOnlySpan<char> Text { get; set; }
    public ReadOnlySpan<char> Current { get; private set; }

    public LineEnumerator(ReadOnlySpan<char> text) {
        Text = text;
        Current = default;
    }

    public LineEnumerator GetEnumerator() {
        return this;
    }

    public bool MoveNext() {
        if (Text.IsEmpty) return false;

        var index = Text.IndexOf(  
  ); // 
 or 

        if (index != -1) {
            Current = Text.Slice( 0, index + 1 );
            Text = Text.Slice( index + 1 );
            return true;
        } else {
            Current = Text;
            Text = ReadOnlySpan<char>.Empty;
            return true;
        }
    }


}

很晚,但我用简单的方式收集了延期方法,以利用<代码>TextReader。 ReadLine(:

public static class StringReadLinesExtension
{
    public static IEnumerable<string> GetLines(this string text) => GetLines(new StringReader(text));
    public static IEnumerable<string> GetLines(this Stream stm) => GetLines(new StreamReader(stm));
    public static IEnumerable<string> GetLines(this TextReader reader) {
        string line;
        while ((line = reader.ReadLine()) != null)
            yield return line;
        reader.Dispose();
        yield break;
    }
}

使用该守则确实是三角的:

// If you have the text as a string...
var text = "Line 1
Line 2
Line 3";
foreach (var line in text.GetLines())
    Console.WriteLine(line);
// You can also use streams like
var fileStm = File.OpenRead("c:	estsfile.txt");
foreach(var line in fileStm.GetLines())
    Console.WriteLine(line);

希望有助于人们走出那里。





相关问题