在richtextbox中查找所有换行符

时间:2018-10-11 10:45:34

标签: c# .net winforms richtextbox

我正在使用自定义texteditor控件,并且遇到了此问题。

我需要一个函数来获取文本中每个换行符“ \ n”的字符索引。 我已经有两种方法可以完成此任务:

.ini

并且:

private List<int> GetNewLineLocations()
    {
        var list = new List<int>();
        int ix = 0;
        foreach (var c in this.Text)
        {
            if (c == '\n') list.Add(ix);
            ix++;
        }
        Debug.WriteLine(ix);
        return list;
    }

第一个解决方案确实有效,但是会降低在Richtextbox中输入的文本的数量,该文本大约包含40000个字符,但可以在很多行(如20000)中分散显示。

第二个似乎更快,因为它更少地循环并且执行或多或少相同的操作,但是在1000行中却急剧降低了速度,没有包含多少文本。

代码当然需要快速运行,并且不使用大量资源,这就是为什么我认为第二种解决方案会更好。

我的问题是:

  1. 哪种解决方案更好,为什么?

  2. 第二个解决方案为什么要慢得多?

  3. 有没有更好的解决方案?

2 个答案:

答案 0 :(得分:1)

我使用富文本框和40k行尝试了您的示例和Felix的示例,以及自己的解决方案。结果是这是最快的,但我没有发现速度变慢。您可以尝试将线数组作为参数传递并让我们知道结果吗?

public static List<int> GetNewLineLocations(this string[] lines)
        {
            var list = new List<int>();
            int ix = -1;

            for (int i = 0; i < lines.Length; i++)
            {
                ix += lines[i].Length+1;
                list.Add(ix);
            }

            return list;
        }

答案 1 :(得分:0)

使用字符串Regular Expressions时非常好用。但是它们并不是最快的。如果需要更快的处理,则应在较低级别上并行进行。并确保使用long as索引,因为int仅允许您最多处理2 ^ 31个字符,而最长只能处理2 ^ 63个字符。

我同意@Nyerguds 谁在评论中说:

  

问题在于,在富文本框中获取文本的标准函数实际上是一个处理函数,必须过滤掉RTF标记。提取文本的实际功能是瓶颈,而不是瓶颈。

因此,您的数据应保存在代码中的某个位置,而不是用户界面中。处理较长的文本迟早会导致麻烦,例如滚动时结结或出现更多瓶颈。而且我只会代表仍然可以在控件中显示的行。因此,您应该考虑一下您的应用程序设计。 Check your Front/Backend seperation.将数据存储在后端将使您可以直接访问数据,而无需依赖于Textbox方法或其他用户界面内容。

这里是一个示例,展示了如何使用.net框架的Parallel Class轻松处理数据:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApp1
    {
        internal class Program
        {
            public static byte[] _globalDataStore { get; set; }
            private static void Main(string[] args)
            {
                DoStuff();
                ShowDone();
            }

            private static void ShowDone()
            {
                Console.WriteLine("done...");
                Console.ReadKey();
            }

            private static void DoStuff()
            {
                var tempData = GetData();
                StoreData(ref tempData);
                tempData = null; //free some ram
                var dataIdentifier = (byte)'\n';
                GetAndPromptDataPositions(_globalDataStore, dataIdentifier);
            }

            private static void GetAndPromptDataPositions<T>(T[] data, T dataIdentifier)
            {
                var dataPositionList = GetDataPositions<T>(data, dataIdentifier);
                PromptDataPostions(dataPositionList);
            }

            private static void PromptDataPostions(IEnumerable<long> positionList)
            {
                foreach (var position in positionList)
                {
                    Console.WriteLine($"Position '{position}'");
                }
            }
            private static string GetData()
            {
                return "aasdlj\naksdlkajsdlkasldj\nasld\njkalskdjasldjlasd";
            }

            private static void StoreData(ref string tempData)
            {
                _globalDataStore = Encoding.ASCII.GetBytes(tempData);
            }

            private static List<long> GetDataPositions<T>(T[] data, T dataToFind)
            {
                lock (data) //prevent data from being changed while processing, important when have other threaded could write data 
                {
                    var postitonList = new List<long>();
                    Parallel.For(0, data.LongLength, (position) =>
                    {
                        if (data[position].Equals(dataToFind))
                        {
                            lock (postitonList) //lock list because of multithreaded access to prevent data corruption
                            {
                                postitonList.Add(position);
                            }
                        }
                    });
                    return postitonList;
                }
            }
        }
    }