如何禁用Delphi中Masks.MatchesMask()的[]集合匹配功能?
解决Delphi中Masks.MatchesMask()匹配含方括号字符的问题
方法1:转义掩码中的方括号
Masks.MatchesMask默认将[]视为字符集合匹配符,要匹配字面意义的[和],需在掩码中对其转义:
- 匹配字面
[:在掩码中写成[[] - 匹配字面
]:在掩码中写成[]]
针对你的场景,修改后的代码示例:
if MatchesMask('C:\Path\File[Name.dat', 'C:\*\File[[*.dat') then // 匹配成功执行逻辑
方法2:自定义匹配函数(完全禁用[]集合功能)
如果需要彻底让[]作为普通字符参与匹配,可自行实现仅支持*(任意长度字符)和?(单个字符)的简化匹配函数:
function SimpleMatchMask(const AText, AMask: string): Boolean; var TextIdx, MaskIdx: Integer; TextLen, MaskLen: Integer; begin Result := False; TextIdx := 1; MaskIdx := 1; TextLen := Length(AText); MaskLen := Length(AMask); while (TextIdx <= TextLen) and (MaskIdx <= MaskLen) do begin if AMask[MaskIdx] = '*' then begin if MaskIdx = MaskLen then begin Result := True; Exit; end; Inc(MaskIdx); while TextIdx <= TextLen do begin if SimpleMatchMask(Copy(AText, TextIdx, TextLen - TextIdx + 1), Copy(AMask, MaskIdx, MaskLen - MaskIdx + 1)) then begin Result := True; Exit; end; Inc(TextIdx); end; Result := False; Exit; end else if (AMask[MaskIdx] = '?') or (AMask[MaskIdx] = AText[TextIdx]) then begin Inc(TextIdx); Inc(MaskIdx); end else begin Result := False; Exit; end; end; while (MaskIdx <= MaskLen) and (AMask[MaskIdx] = '*') do Inc(MaskIdx); Result := (TextIdx > TextLen) and (MaskIdx > MaskLen); end;
使用示例:
if SimpleMatchMask('C:\Path\File[Name.dat', 'C:\*\File[*.dat') then // 匹配成功执行逻辑
方法3:预处理掩码与文本
将掩码和目标文本中的[、]替换为不会触发集合匹配的临时字符,再调用MatchesMask:
function MatchWithLiteralBrackets(const AText, AMask: string): Boolean; var ProcessedText, ProcessedMask: string; begin ProcessedText := StringReplace(AText, '[', '#[#', [rfReplaceAll]); ProcessedText := StringReplace(ProcessedText, ']', '#]#', [rfReplaceAll]); ProcessedMask := StringReplace(AMask, '[', '#[#', [rfReplaceAll]); ProcessedMask := StringReplace(ProcessedMask, ']', '#]#', [rfReplaceAll]); Result := MatchesMask(ProcessedText, ProcessedMask); end;
这种方法通过替换让方括号变为普通字符串片段,避免被识别为集合匹配符。
内容的提问来源于stack exchange,提问作者user2972081
相关产品推荐
相关产品推荐

