在 RichTextBox C# Windows 表单中突出显示不平衡的括号
Highlighting Unbalanced Parentheses in RichTextBox C# Windows Forms
我目前有一个 Windows 表单设置,它在 RichTextBox 中采用数学表达式,并在表达式中搜索任何不平衡的括号。我的表单由 RichTextBox 和一个显示 "Check Parens" 的按钮组成。我也在尝试使用堆栈检查不平衡的括号。我想要的是以某种方式指出哪些括号是不平衡的。我想通过突出显示或加粗 RichTextBox 中的括号来做到这一点。有没有办法用我现在设置的代码来做到这一点?下面是我的代码,非常感谢任何建设性的反馈!
public partial class checkParentheses : Form
{
const char leftParens = '(';
const char rightParens = ')';
public checkParentheses()
{
InitializeComponent();
}
public void checkParensButton_Click(object sender, EventArgs e)
{
int value;
checkBalancedParens(mathEquation.Text, out value);
}
bool checkBalancedParens(string expression, out int error)
{
var parens = new Stack<int>(expression.Length);//Create stack
error = -1; //Error at -1
for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses
{
char p = expression[i];
if (p == leftParens)//if p finds left parens
{
parens.Push(i);//push to top of stack
}
else if (p == rightParens)//if p finds right parens
{
if (parens.Count == 0)//if stack has zero items
{
error = i + 1;
return false;
}
parens.Pop();//Returns to top of stack
}
}
if (parens.Count > 0)//if stack has more than 0 items
{
error = parens.Peek() + 1; //Peek at top of stack
MessageBox.Show("Unbalanced");
return false;
}
MessageBox.Show("Balanced");//Otherwise, expression is balanced
return true;
}
}
编辑:鉴于下面的解决方案,这是次等的。如果您想加粗文本,示例仍然包含在内。您可以将 HighlightOffenders 方法替换为
private void HighlightOffenders(IEnumerable<int> listOfIndexes)
{
foreach (var index in listOfIndexes.Reverse())
{
mathEquation.Select(index,1);
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold);
}
}
因此,您应该跟踪左括号索引和右括号索引。然后从各自的堆栈中弹出匹配对。
就显示文本而言,我不知道这是否是最佳方式,但这是可行的方式。它需要重建字符串,但会将正确的结果放入 RichTextBox 中。您需要忽略我的表单名为 "Form1" 的事实,并将其替换为 "checkParentheses"。可能有一种方法可以在实际字符之上绘制突出显示,但我不熟悉它。
public partial class Form1 : Form
{
const char leftParenChar = '(';
const char rightParenChar = ')';
public Form1()
{
InitializeComponent();
}
public void checkParensButton_Click(object sender, EventArgs e)
{
checkBalancedParens(mathEquation.Text);
}
bool checkBalancedParens(string expression)
{
var leftParensIndexes = new Stack<int>(expression.Length);
var rightParensIndexes = new Stack<int>(expression.Length);
var isError = false;
for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses
{
char p = expression[i];
if (p == leftParenChar)//if p finds left parens
{
leftParensIndexes.Push(i);//push to top of stack
}
else if (p == rightParenChar)//if p finds right parens
{
rightParensIndexes.Push(i);
//keep a record if there is an error, but don't stop yet.
if (leftParensIndexes.Count == 0)
{
isError = true;
}
else
{
//eliminate the matching pair if it exists
rightParensIndexes.Pop();
leftParensIndexes.Pop();
}
}
}
if (leftParensIndexes.Count > 0)//if stack has more than 0 items
{
isError = true;
}
HighlightOffenders(rightParensIndexes.Concat(leftParensIndexes));
return !isError;
}
private void HighlightOffenders(IEnumerable<int> listOfIndexes)
{
var text = mathEquation.Text;
mathEquation.Clear();
int lastIndex = 0; //store the last index you finished at (for string math)
int count = 0; //the number of items that we've added (also for string math)
foreach (var index in listOfIndexes.Reverse())
{
mathEquation.AppendText(text.Substring(lastIndex, index - lastIndex - count));
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold);
mathEquation.AppendText(text.Substring(index,1));
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Regular);
lastIndex = index;
count++;
}
mathEquation.AppendText(text.Substring(lastIndex + count-1, text.Length - lastIndex - count + 1));
}
}
此处描述了在 RichEdit 中突出显示文本 here
.完整的解决方案:
private void checkParensButton_Click(object sender, EventArgs e)
{
// clean up previous selection
mathEquation.SelectAll();
mathEquation.SelectionBackColor = Color.White;
var indexes = EnumerateUnbalancedParentheses(mathEquation.Text);
foreach (var index in indexes)
{
mathEquation.Select(index, 1);
mathEquation.SelectionBackColor = Color.Aqua;
}
}
private static IEnumerable<int> EnumerateUnbalancedParentheses(string expression)
{
var openingParentheses = new Stack<int>();
var closingParentheses = new Stack<int>();
for (var i = 0; i < expression.Length; ++i)
{
var symbol = expression[i];
if (symbol == '(')
{
openingParentheses.Push(i);
}
else if (symbol == ')')
{
if (openingParentheses.Count > 0)
openingParentheses.Pop();
else
closingParentheses.Push(i);
}
}
return openingParentheses.Concat(closingParentheses);
}
我目前有一个 Windows 表单设置,它在 RichTextBox 中采用数学表达式,并在表达式中搜索任何不平衡的括号。我的表单由 RichTextBox 和一个显示 "Check Parens" 的按钮组成。我也在尝试使用堆栈检查不平衡的括号。我想要的是以某种方式指出哪些括号是不平衡的。我想通过突出显示或加粗 RichTextBox 中的括号来做到这一点。有没有办法用我现在设置的代码来做到这一点?下面是我的代码,非常感谢任何建设性的反馈!
public partial class checkParentheses : Form
{
const char leftParens = '(';
const char rightParens = ')';
public checkParentheses()
{
InitializeComponent();
}
public void checkParensButton_Click(object sender, EventArgs e)
{
int value;
checkBalancedParens(mathEquation.Text, out value);
}
bool checkBalancedParens(string expression, out int error)
{
var parens = new Stack<int>(expression.Length);//Create stack
error = -1; //Error at -1
for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses
{
char p = expression[i];
if (p == leftParens)//if p finds left parens
{
parens.Push(i);//push to top of stack
}
else if (p == rightParens)//if p finds right parens
{
if (parens.Count == 0)//if stack has zero items
{
error = i + 1;
return false;
}
parens.Pop();//Returns to top of stack
}
}
if (parens.Count > 0)//if stack has more than 0 items
{
error = parens.Peek() + 1; //Peek at top of stack
MessageBox.Show("Unbalanced");
return false;
}
MessageBox.Show("Balanced");//Otherwise, expression is balanced
return true;
}
}
编辑:鉴于下面的解决方案,这是次等的。如果您想加粗文本,示例仍然包含在内。您可以将 HighlightOffenders 方法替换为
private void HighlightOffenders(IEnumerable<int> listOfIndexes)
{
foreach (var index in listOfIndexes.Reverse())
{
mathEquation.Select(index,1);
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold);
}
}
因此,您应该跟踪左括号索引和右括号索引。然后从各自的堆栈中弹出匹配对。
就显示文本而言,我不知道这是否是最佳方式,但这是可行的方式。它需要重建字符串,但会将正确的结果放入 RichTextBox 中。您需要忽略我的表单名为 "Form1" 的事实,并将其替换为 "checkParentheses"。可能有一种方法可以在实际字符之上绘制突出显示,但我不熟悉它。
public partial class Form1 : Form
{
const char leftParenChar = '(';
const char rightParenChar = ')';
public Form1()
{
InitializeComponent();
}
public void checkParensButton_Click(object sender, EventArgs e)
{
checkBalancedParens(mathEquation.Text);
}
bool checkBalancedParens(string expression)
{
var leftParensIndexes = new Stack<int>(expression.Length);
var rightParensIndexes = new Stack<int>(expression.Length);
var isError = false;
for (int i = 0; i < expression.Length; i++)//Check for unbalanced Parentheses
{
char p = expression[i];
if (p == leftParenChar)//if p finds left parens
{
leftParensIndexes.Push(i);//push to top of stack
}
else if (p == rightParenChar)//if p finds right parens
{
rightParensIndexes.Push(i);
//keep a record if there is an error, but don't stop yet.
if (leftParensIndexes.Count == 0)
{
isError = true;
}
else
{
//eliminate the matching pair if it exists
rightParensIndexes.Pop();
leftParensIndexes.Pop();
}
}
}
if (leftParensIndexes.Count > 0)//if stack has more than 0 items
{
isError = true;
}
HighlightOffenders(rightParensIndexes.Concat(leftParensIndexes));
return !isError;
}
private void HighlightOffenders(IEnumerable<int> listOfIndexes)
{
var text = mathEquation.Text;
mathEquation.Clear();
int lastIndex = 0; //store the last index you finished at (for string math)
int count = 0; //the number of items that we've added (also for string math)
foreach (var index in listOfIndexes.Reverse())
{
mathEquation.AppendText(text.Substring(lastIndex, index - lastIndex - count));
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Bold);
mathEquation.AppendText(text.Substring(index,1));
mathEquation.SelectionFont = new Font(mathEquation.Font, FontStyle.Regular);
lastIndex = index;
count++;
}
mathEquation.AppendText(text.Substring(lastIndex + count-1, text.Length - lastIndex - count + 1));
}
}
此处描述了在 RichEdit 中突出显示文本 here .完整的解决方案:
private void checkParensButton_Click(object sender, EventArgs e)
{
// clean up previous selection
mathEquation.SelectAll();
mathEquation.SelectionBackColor = Color.White;
var indexes = EnumerateUnbalancedParentheses(mathEquation.Text);
foreach (var index in indexes)
{
mathEquation.Select(index, 1);
mathEquation.SelectionBackColor = Color.Aqua;
}
}
private static IEnumerable<int> EnumerateUnbalancedParentheses(string expression)
{
var openingParentheses = new Stack<int>();
var closingParentheses = new Stack<int>();
for (var i = 0; i < expression.Length; ++i)
{
var symbol = expression[i];
if (symbol == '(')
{
openingParentheses.Push(i);
}
else if (symbol == ')')
{
if (openingParentheses.Count > 0)
openingParentheses.Pop();
else
closingParentheses.Push(i);
}
}
return openingParentheses.Concat(closingParentheses);
}