如何有效地从C#中的字符串中选择子字符串

时间:2019-02-12 12:18:53

标签: c#

我正在尝试选择特定的字符串“ Compression:”,在这种情况下为Deflate

下面是代码:

static void Main(string[] args)
{
    var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" + 
        "         File type: binary\n       Compression: Deflate\n        " + 
        "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

    string s1 = info.Substring((info.IndexOf("Compression:")), 
        info.Length - info.IndexOf("Compression:") - 1);

    var replace = s1.Replace("Compression: ", "");
}

在这里,我得到的所有字符串都具有子字符串“ Compression

是否有一种有效的方法来仅获取Deflate中的Compression

谢谢!

8 个答案:

答案 0 :(得分:2)

您可以将df = pd.DataFrame(response,index=[value]) 字符上的字符串分割成一组名称/值对,然后找到一个以您的搜索字符串(\n)开头的字符串,然后在{ {1}}字符并返回第二部分。

为概括起见,您可以编写一个函数,该函数接受您的搜索字符串和要搜索的字符串,如果找到则返回指定名称的值(如果找不到则返回"Compression"):

:

然后您可以使用不同的“名称”来调用它们以查找其值:

null

输出

enter image description here

或者,您可以编写该方法,以便它以public static string GetValue(string name, string source) { if (source == null || name == null) return null; var result = source.Split('\n') .Select(i => i.Trim()) .FirstOrDefault(i => i.StartsWith(name + ":", StringComparison.OrdinalIgnoreCase)) ?.Split(':'); return result?.Length == 2 ? result[1].Trim() : null; } 的形式从字符串中返回 ALL 键/值对。然后,您可以按名称查找值:

private static void Main()
{
    var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" +
                "         File type: binary\n       Compression: Deflate\n        " +
                "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

    var compression = GetValue("Compression", info);
    var zipEntry = GetValue("ZipEntry", info);

    Console.WriteLine($"Compression = {compression}, ZipEntry = {zipEntry}");

    GetKeyFromUser("\nDone! Press any key to exit...");
}

例如:

Dictionary<string, string>

输出

![enter image description here

答案 1 :(得分:1)

假设所有前导和尾随空间都无用,那么您可以使用Splitlinq来做到这一点。说明在代码注释中。

var compressionValue = info
     // Process data per line 
    .Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)
     // Remove leading and trailing space
    .Select(s => s.Trim())
    // Check for "Compression" header
    .Where(r => r.StartsWith("Compression: "))
    // Get corresponding value
    .Select(s => s.Substring("Compression: ".Length))
    // Select the first Match, null if "Compression : " is not found
    .FirstOrDefault();

答案 2 :(得分:0)

当然,您也可以使用Substring()将字符串切成小块。

但是使用正则表达式最容易实现:

static void Main(string[] args)
{
    var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" + 
        "         File type: binary\n       Compression: Deflate\n        " + 
        "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

    MatchCollection matches = Regex.Matches(info, @"(?<=Compression: )([^\\n]*)");

    foreach (Match match in matches)
    {
        Debug.WriteLine($"- Match: {match.Value}");
    }
}

正则表达式使用lookaround(在这种情况下,尤其是lookbehind)子句来检查“ Compression:”开头的字符串。然后,它开始捕获不是\n的任何字符(必须两次转义)。其他所有东西都被丢弃。

答案 3 :(得分:0)

如果您确定它将是\ Deflate值之后的\ n,则可以执行以下操作:

if(s1.Contains('\n'))
{
     s1 = s1.Split('\n')[0];
}
var replace = s1.Replace("Compression: ", "");

答案 4 :(得分:0)

static void Main(string[] args)
{

    var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" +
        "         File type: binary\n       Compression: Deflate\n        " +
        "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n  ";
    List<string> splittedinfo = info.Split('\n');
    foreach (string s in splittedinfo)
    {
        if (!string.IsNullOrEmpty(s.Trim()))
        {
            var ss = s.Split(':');
            if (ss[0].Trim() == "Compression")
            {
                Console.WriteLine(ss[1]);
                break;
            }
        }
    }
    Console.ReadLine();
}

static void Main(string[] args)
{
    string key = "Compressed",  endstring = "\n";
    char separator = ':';
    var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" +
        "         File type: binary\n       Compression: Deflate\n        " +
        "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n  ";

    info = info.Substring(info.IndexOf(key));
    info = info.Substring(0, info.IndexOf(endstring));
    info = info.Split(separator)[1].Trim();
    Console.WriteLine(info);
    Console.ReadLine();
}

答案 5 :(得分:0)

我会将字符串解析为字典,以便您可以轻松访问任何所需的值:

        var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n         File type: binary\n       Compression: Deflate\n        Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

        var values = new Dictionary<string, string>();
        IList<string> split = info.Split(new char[] { ':', '\n' }).Select(x => x.Trim()).ToList();

        if (split.Count > 0)
        {
            for (int i = 1; i < split.Count; i++)
            {
                if (i % 2 != 0)
                    values.Add(split[i - 1], split[i]);
                else if (i == split.Count - 1)
                    values.Add(split[i], "");
            }
        }

        string compression = values["Compression"];

答案 6 :(得分:0)

  

有没有一种有效的方法来仅获取压缩放气?

您可以使用.NET Core 2.1和System.Memory NuGet package中引入的Span<T> / ReadOnlySpan<char>类型:

static void Main(string[] args)
{
    string info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n" +
            "         File type: binary\n       Compression: Deflate\n        " +
            "Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

    ReadOnlySpan<char> span = info.AsSpan();
    ReadOnlySpan<char> compression = "Compression: ".AsSpan();
    int startIndex = span.IndexOf(compression);
    if (startIndex != -1)
    {
        ReadOnlySpan<char> deflate = span.Slice(startIndex + compression.Length);
        int endIndex = deflate.IndexOf('\n');
        if (endIndex != -1)
        {
            string s1 = deflate.Slice(0, endIndex).ToString();
        }
    }
}

它使您不必徒劳地分配必要的子字符串和分配的内存。有关更多信息,请参阅Stephen Toub's MSDN Magazine article

答案 7 :(得分:-1)

尝试一下:

            var info = "ZipEntry: testfile.txt\n   Version Made By: 45\n Needed to extract: 45\n         File type: binary\n       Compression: Deflate\n        Compressed: 0x35556371\n      Uncompressed: 0x1D626FBDB\n      ...";

            var newArray = info.Split('\n');

            foreach (var item in newArray)
            {
                if (item.Contains("Compression:"))
                {
                    var value = item.Split(':')[1];
                    return value;
                }
            }