提取两个字符串之间的所有字符串

时间:2012-12-08 18:44:58

标签: c#

我正在尝试开发一种方法来匹配两个字符串之间的所有字符串:

我试过这个,但它只返回第一场比赛:

string ExtractString(string s, string start,string end)
        {
            // You should check for errors in real-world code, omitted for brevity

            int startIndex = s.IndexOf(start) + start.Length;
            int endIndex = s.IndexOf(end, startIndex);
            return s.Substring(startIndex, endIndex - startIndex);
        }

我们假设我们有这个字符串

String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"

我想要一个c#函数执行以下操作:

public List<string> ExtractFromString(String Text,String Start, String End)
{
    List<string> Matched = new List<string>();
    .
    .
    .
    return Matched; 
}
// Example of use 

ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2")

    // Will return :
    // FIRSTSTRING
    // SECONDSTRING
    // THIRDSTRING

感谢您的帮助!

5 个答案:

答案 0 :(得分:27)

    private static List<string> ExtractFromBody(string body, string start, string end)
    {
        List<string> matched = new List<string>();

        int indexStart = 0;
        int indexEnd = 0;

        bool exit = false;
        while (!exit)
        {
            indexStart = body.IndexOf(start);

            if (indexStart != -1)
            {
                indexEnd = indexStart + body.Substring(indexStart).IndexOf(end);

                matched.Add(body.Substring(indexStart + start.Length, indexEnd - indexStart - start.Length));

                body = body.Substring(indexEnd + end.Length);
            }
            else
            {
                exit = true;
            }
        }

        return matched;
    }

答案 1 :(得分:10)

这是使用RegEx的解决方案。不要忘记包含以下使用声明。

using System.Text.RegularExpressions

它将正确返回给定的开始和结束字符串之间的文本。

不会退回:

akslakhflkshdflhksdf

将被退回:

FIRSTSTRING
SECONDSTRING
THIRDSTRING

它使用正则表达式模式[start string].+?[end string]

如果开始和结束字符串包含正则表达式特殊字符,则会对其进行转义。

    private static List<string> ExtractFromString(string source, string start, string end)
    {
        var results = new List<string>();

        string pattern = string.Format(
            "{0}({1}){2}", 
            Regex.Escape(start), 
            ".+?", 
             Regex.Escape(end));

        foreach (Match m in Regex.Matches(source, pattern))
        {
            results.Add(m.Groups[1].Value);
        }

        return results;
    }

您可以将其转换为String的扩展方法,如下所示:

public static class StringExtensionMethods
{
    public static List<string> EverythingBetween(this string source, string start, string end)
    {
        var results = new List<string>();

        string pattern = string.Format(
            "{0}({1}){2}",
            Regex.Escape(start),
            ".+?",
             Regex.Escape(end));

        foreach (Match m in Regex.Matches(source, pattern))
        {
            results.Add(m.Groups[1].Value);
        }

        return results;
    }
}

用途:

string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
string start = "A1";
string end = "A2";

List<string> results = source.EverythingBetween(start, end);

答案 2 :(得分:4)

text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries);

答案 3 :(得分:1)

您可以使用以下代码中的起始标识符将字符串拆分为数组:

String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";

String[] arr = str.Split("A1");

然后遍历您的数组并删除每个字符串的最后2个字符(以删除A2)。您还需要丢弃第一个数组元素,因为它将为空,假设字符串以A1开头。

代码未经测试,目前在移动设备上

答案 4 :(得分:0)

这是一个通用解决方案,我相信代码更具可读性。未经测试,请注意。

public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> source, 
                                               Func<T, bool> startPredicate,
                                               Func<T, bool> endPredicate, 
                                               bool includeDelimiter)
{
    var l = new List<T>();
    foreach (var s in source)
    {
        if (startPredicate(s))
        {
            if (l.Any())
            {
                l = new List<T>();
            }
            l.Add(s);
        }
        else if (l.Any())
        {
            l.Add(s);
        }

        if (endPredicate(s))
        {
            if (includeDelimiter)
                yield return l;
            else
                yield return l.GetRange(1, l.Count - 2);

            l = new List<T>();
        }
    }
}

在你的情况下你可以打电话,

var text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
var splits = text.SplitBy(x => x == "A1", x => x == "A2", false);

当您不希望在结果中包含分隔符(如您的情况)但对于相反的情况有效时,这不是最有效的。为了加速你的情况,你可以直接调用GetEnumerator并使用MoveNext。