12

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

我已经尝试过了,但它只返回第一个匹配项:

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"

我希望 ac# 函数执行以下操作:

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

感谢您的帮助 !

4

5 回答 5

35
    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;
    }
于 2012-12-08T18:57:16.040 回答
15

这是使用 RegEx 的解决方案。不要忘记包含以下 using 语句。

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);
于 2012-12-08T19:18:44.783 回答
3
text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries);
于 2012-12-08T19:00:16.657 回答
2

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

String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";

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

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

代码未经测试,目前在手机上

于 2012-12-08T18:54:29.027 回答
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。

于 2015-07-25T09:47:47.853 回答