我怀疑您是否While
以不正确的方式设置了循环。
尝试这样的事情:(未经测试,但会给你一个如何解决这个问题的想法)
rtbMain.SelectAll();
rtbMain.SelectionColor = Color.Black;
rtbMain.SelectionBackColor = Color.White;
Regex regex = new Regex(txtRegexPattern.Text, regexOptions);
MatchCollection matches = regex.Matches(txtTest.Text);
if(matches.Count > 0)
{
foreach(Match m in matches)
{
rtbMain.Select(m.Index, m.Length);
rtbMain.SelectionColor = Color.Red;
rtbMain.SelectionBackColor = Color.Black;
}
}
else
{
Debug.Print("No matches found"); // See "Output" Window
}
编辑
我做了一些与突出显示 RTF 文本相关的解决方法,我发现的第一件事是该过程花费的大部分时间是以下几行:
rtbMain.SelectionColor = Color.Red;
rtbMain.SelectionBackColor = Color.Black;
我尝试使用SelectionStart
和SelectionEnd
属性来选择文本.Select()
,但没有观察到任何变化。
关于与构建等效RTF有关的第一点,我也尝试过,但是很难构建等效的RTF,因为那里有很多东西需要处理。如果可以完成,处理时间将小于 1.5 秒,超过 31k 匹配(特定样本的基本测试结果)。
因此,我建议您通过THREADING执行此操作并将任务拆分为两个线程:
这是一个示例源代码:(在最坏的情况下,我发现大约 31341 个匹配项,处理过程需要 4 秒才能突出显示)
// declare variables either globally or in the same method
MatchCollection mcoll;
Stopwatch s;
int callbackCount = 0;
List<Match> m1 = null;
List<Match> m2 = null;
private void btnHighlight_Click(object sender, EventArgs e)
{
//reset any exisiting formatting
rtbMain.SelectAll();
rtbMain.SelectionBackColor = Color.White;
rtbMain.SelectionColor = Color.Black;
rtbMain.DeselectAll();
s = new Stopwatch();
s.Start();
Regex re = new Regex(@"(.)", RegexOptions.Compiled); // Notice COMPILED option
mcoll = re.Matches(rtbMain.Text);
// Break MatchCollection object into List<Matches> which is exactly half in size
m1 = new List<Match>(mcoll.Count / 2);
m2 = new List<Match>(mcoll.Count / 2);
for (int k = 0; k < mcoll.Count; k++)
{
if (k < mcoll.Count / 2)
m1.Add(mcoll[k]);
else
m2.Add(mcoll[k]);
}
Thread backgroundThread1 = new Thread(new ThreadStart(() => {
match1(null, null);
}));
backgroundThread1.Start();
Thread backgroundThread2 = new Thread(new ThreadStart(() =>
{
match2(null, null);
}));
backgroundThread2.Start();
}
public void match1(object obj, EventArgs e)
{
for (int i=0; i < m1.Count; i += 1)
{
if (rtbMain.InvokeRequired)
{
EventHandler d = new EventHandler(match1);
rtbMain.Invoke(d);
}
else
{
rtbMain.Select(m1[i].Index, m1[i].Length);
rtbMain.SelectionBackColor = Color.Black;
rtbMain.SelectionColor = Color.Red;
}
}
stopTimer();
}
public void match2(object obj, EventArgs e)
{
for (int j=0; j < m2.Count; j += 1)
{
if (rtbMain.InvokeRequired)
{
EventHandler d = new EventHandler(match2);
rtbMain.Invoke(d);
}
else
{
rtbMain.Select(m2[j].Index, m2[j].Length);
rtbMain.SelectionBackColor = Color.Black;
rtbMain.SelectionColor = Color.Red;
}
}
stopTimer();
}
void stopTimer()
{
callbackCount++;
if (callbackCount == 2) // 2 because I am using two threads.
{
s.Stop();
// Check Output Window
Debug.Print("Evaluated in : " + s.Elapsed.Seconds.ToString());
}
}
由于您发布的操作大约需要 30 秒,因此希望 4 秒是可以忍受的,并且用户可以像Rubular和DerekSlager 的 .Net 正则表达式测试器那样的其他在线转换器那样通过一些加载屏幕来吸引用户。
不要忘记查看为什么 Regex.Compiled 首选。