微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

(C#)提高自定义getBetweenAll的速度

我在c#中编写了一个自定义扩展方法,它是对extensionmethod string [] getBetweenAll(string source,string startstring,string endstring)的改进;

最初这个扩展方法找到了两个字符串之间的所有子串,例如:

string source = "<1><2><3><4>";
source.getBetweenAll("<",">");
//output: string[] {"1","2","3","4"}

但如果你有另一次出现<在一开始它只会介于那个和整个字符串之间

string source = "<<1><2><3><4>";
source.getBetweenAll("<",">");
//output: string[] {"<1><2><3><4"}

所以我重新编写它以更精确地从“>”向后搜索找到第一次出现的“<” 现在我得到了它的工作,但问题是它太慢了,因为搜索方法会跳过每次出现的整个字符串的每个字符.你知道我怎么能提高这个功能的速度吗?还是不可能? 这是到目前为止http://pastebin.com/JEZmyfSG的完整代码
我已经添加代码需要提高速度的注释

public static List<int> IndexOfAll(this string main,string searchString)
{
    List<int> ret = new List<int>();
    int len = searchString.Length;
    int start = -len;
    while (true)
    {
        start = main.IndexOf(searchString,start + len);
        if (start == -1)
        {
            break;
        }
        else
        {
            ret.Add(start);
        }
    }
    return ret;
}

public static string[] getBetweenAll(this string main,string strstart,string strend,bool preserve = false)
{
    List<string> results = new List<string>();
    List<int> ends = main.IndexOfAll(strend);
    foreach (int end in ends)
    {
        int start = main.prevIoUsIndexOf(strstart,end);  //This is where it has to search the whole source string every time
        results.Add(main.Substring(start,end - start) + (preserve ? strend : string.Empty));
    }
    return results.ToArray();
}

//This is the slow function (depends on main.Length)
public static int prevIoUsIndexOf(this string main,string find,int offset)
{
    int wtf = main.Length ;
    int x = main.LastIndexOf(find,wtf);
    while (x > offset)
    {
        x = main.LastIndexOf(find,wtf);
        wtf -= 1;
    }
    return x;
}

我想另一种做PrevIoUsIndexOf的方法(string,int searchfrom);会提高速度..比如IndexOf()除了向后和提供的起始偏移

解决方法

作为原始的GetBetweenAll,我们可以使用正则表达式.为了仅匹配封闭字符串的最短“内部”外观,我们必须在起始字符串上使用负向前瞻,并为内容使用非贪婪量词.

public static string[] getBetweenAll(this string main,bool preserve = false)
{
    List<string> results = new List<string>();

    string regularExpressionString = string.Format("{0}(((?!{0}).)+?){1}",Regex.Escape(strstart),Regex.Escape(strend));
    Regex regularExpression = new Regex(regularExpressionString,RegexOptions.IgnoreCase);

    var matches = regularExpression.Matches(main);

    foreach (Match match in matches)
    {
        if (preserve)
        {
            results.Add(match.Value);
        }
        else
        {
            results.Add(match.Groups[1].Value);
        }
    }

    return results.ToArray();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐