C# 在richtextbox中查找所有换行符
我正在处理一个自定义texteditor控件,遇到了这个问题 我需要一个函数来获取文本中每个换行符“\n”的字符索引。 我有两种方法来实现这一点:C# 在richtextbox中查找所有换行符,c#,.net,winforms,richtextbox,C#,.net,Winforms,Richtextbox,我正在处理一个自定义texteditor控件,遇到了这个问题 我需要一个函数来获取文本中每个换行符“\n”的字符索引。 我有两种方法来实现这一点: private List<int> GetNewLineLocations() { var list = new List<int>(); int ix = 0; foreach (var c in this.Text) { if
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;
}
private List GetNewLineLocations()
{
var list=新列表();
int ix=0;
foreach(此.Text中的var c)
{
如果(c=='\n')列表。添加(ix);
ix++;
}
调试写线(ix);
退货清单;
}
以及:
private List GetNewLineLocations()
{
var list=新列表();
int ix=-1;
for(int i=0;i
第一种解决方案确实有效,但会减慢在richtextbox中输入的文本的速度。richtextbox大约有40000个字符,但可以分散在许多行中,如20000个
第二个似乎更快,因为它循环次数更少,做的也差不多,但在1000行时,无论包含多少文本,速度都会显著减慢
代码当然需要快速运行,而不是占用大量资源,这就是为什么我认为第二种解决方案会更好的原因
我的问题是:
问题在于,在富文本框中提取文本的标准函数实际上是一个必须过滤掉RTF标记的处理函数。获取文本的实际功能是瓶颈,而不是它后面的功能 因此,您的数据应该保存在代码中的某个位置,而不是用户界面中。在处理长文本时,迟早会遇到麻烦,比如滚动时出现口吃或进一步出现瓶颈。我只表示可以在控件中显示的行。因此,您应该过度考虑应用程序设计。将数据存储在后端将允许您直接访问数据,而无需依赖文本框方法或其他用户界面内容 下面是一个如何使用.net framework的简化处理数据的示例:
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;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Threading.Tasks;
名称空间控制台EAPP1
{
内部课程计划
{
公共静态字节[]\u全局数据存储{get;set;}
私有静态void Main(字符串[]args)
{
DoStuff();
ShowDone();
}
私有静态void ShowDone()
{
控制台。WriteLine(“完成…”);
Console.ReadKey();
}
私有静态void DoStuff()
{
var tempData=GetData();
StoreData(参考tempData);
tempData=null;//释放一些ram
变量数据标识符=(字节)'\n';
GetAndPromptDataPositions(_globalDataStore,dataIdentifier);
}
私有静态void GetAndPromptDataPositions(T[]数据,T dataIdentifier)
{
var dataPositionList=GetDataPositions(数据,数据标识符);
PromptDataPositions(数据位置列表);
}
私有静态无效PromptDataPostions(IEnumerable positionList)
{
foreach(位置列表中的var位置)
{
WriteLine($“Position'{Position}'”);
}
}
私有静态字符串GetData()
{
返回“aasdlj\naksdlkajsdlkasldj\nasld\njkalskdjasldd”;
}
私有静态void存储数据(参考字符串tempData)
{
_globalDataStore=Encoding.ASCII.GetBytes(tempData);
}
私有静态列表GetDataPositions(T[]数据,T dataToFind)
{
lock(data)//防止数据在处理时被更改,当其他线程可以写入数据时,这一点很重要
{
var positonlist=新列表();
平行。对于(0,data.LongLength,(位置)=>
{
if(数据[position].Equals(dataToFind))
{
lock(positonlist)//由于多线程访问而锁定列表,以防止数据损坏
{
职位列表。添加(职位);
}
}
});
返回帖子列表;
}
}
}
}
我尝试了您的示例和Felix的,以及我自己的解决方案,使用了一个富文本框和40k行。结果是这是最快的,我看不到任何减速。你能试着把线数组作为参数传递给我们并告诉我们结果吗
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;
}
公共静态列表GetNewLineLocations(此字符串[]行)
{
var list=新列表();
int ix=-1;
对于(int i=0;i
不幸的是,我无法实现这一点。至少没有更好更快的方法,您不需要解析\n
字符和存储索引。您已经有了行和文本框的集合
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;
}