加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 23:22:09 所属栏目:百科 来源:网络整理
导读:我在c#中编写了一个自定义扩展方法,它是对extensionmethod string [] getBetweenAll(string source,string startstring,string endstring)的改进; 最初这个扩展方法找到了两个字符串之间的所有子串,例如: string source = "1234";source.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();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读