关于高亮显示括号匹配的算法(delphi)
环境: SynEdtor控件 + delphi
匹配括号的算法:传入参数 APoint: TBufferCoord;
const
Brackets: array[0..7] of char = ('(', ')', '[', ']', '{', '}', '<', '>');
var
Line: string;
i, PosX, PosY, Len: integer;
Test, BracketInc, BracketDec: char;
NumBrackets: integer;
p: TBufferCoord;
begin
Result.Char := 0;
Result.Line := 0;
// 获取到鼠标的位置
PosX := APoint.Char;
PosY := APoint.Line;
Line := Lines[ APoint.Line -1 ];
if Length(Line) >= PosX then
begin
Test := Line[PosX];
//判断是不是数组里的括号
for i := Low(Brackets) to High(Brackets) do
if Test = Brackets[i] then
begin
// 这里可以得到当前选中的括号与数组的匹配的括号是哪个?
BracketInc := Brackets[i];
BracketDec := Brackets[i xor 1]; // 0 -> 1, 1 -> 0, ...
// NumBrackets 这个计数器很关键,如果等于0。表示找到了匹配的括号
NumBrackets := 1;
if Odd(i) then //判断是否奇数
begin
while (true) do
begin
//数组里为奇数的括号,一直寻址到文本开头
while PosX > 1 do
begin
Dec(PosX);
Test := Line[PosX];
p.Char := PosX;
p.Line := PosY;
if (Test = BracketInc) or (Test = BracketDec) then
begin
if (Test = BracketInc) and (not isCommentOrString) then
Inc(NumBrackets)
else if (Test = BracketDec) and (not isCommentOrString) then
begin
Dec(NumBrackets);
if NumBrackets = 0 then
begin
//找到匹配的括号则跳出
Result := P;
exit;
end;
end;
end;
end;
//while(true)跳出条件
if PosY = 1 then break;
Dec(PosY);
Line := Lines[PosY - 1];
PosX := Length(Line) + 1;
end;
end
else begin
while (true) do
begin
//数组里为偶数的括号,一直寻址到文本开头
Len := Length(Line);
while PosX < Len do
begin
Inc(PosX);
Test := Line[PosX];
p.Char := PosX;
p.Line := PosY;
if (Test = BracketInc) or (Test = BracketDec) then
begin
if (Test = BracketInc) and (not isCommentOrString) then
Inc(NumBrackets)
else if (Test = BracketDec)and (not isCommentOrString) then
begin
Dec(NumBrackets);
if NumBrackets = 0 then
begin
//找到匹配的括号则跳出
Result := P;
exit;
end;
end;
end;
end;
//while(true)跳出条件
if PosY = Lines.Count then
Break;
Inc(PosY);
Line := Lines[PosY - 1];
PosX := 0;
end;
end;
//不在数组的其他字符不做匹配
break;
end;
end;
—–画括号的背景 上面的函数将返回一个 matchBacket: TBufferCoord;
xpos := matchBacket.char;
yPos := matchBacket.line;
windows.SetBkMode(self.Canvas.Handle, windows.OPAQUE);
self.Canvas.Font.Size:= Acontrol.canvas.Font.Size;
self.Canvas.Font.Name:= Acontrol.canvas.Font.name;
windows.TextOut(aControl.canvas.Handle, xpos, ypos, Bracket, 1);
总结:
1、 整个功能的实现过程中,在查找匹配括号中使用了一个计数器,同时利用括号成对的奇偶数的判断思路完成编码。
2、不仅需要找到匹配的括号,还要对这个位置进行背景色的绘制。