我有一个列出部门的子菜单。在这后面,每个部门都有一个名称指定为“actPlan”+部门.名称的操作。
现在我意识到这是一个坏主意,因为名称可以包含世界上任何奇怪的字符,但 action.name 不能包含国际字符。显然,Delphi IDE 本身会调用一些方法来验证字符串是否是有效的组件名称。有人了解更多吗?
我也有一个想法可以使用
Action.name := 'actPlan' + department.departmentID;
相反。优点是,departmentID 是已知格式“xxxxx-x”(其中 x 是 1-9),因此我只需将“-”替换为下划线等。这里的问题是那些旧的操作名称已经保留在个人文本文件中。如果我突然从使用部门名称改为使用ID,那是异常(exception)。
我当然可以第一次处理异常,然后调用一个方法来搜索用正确的数据替换该文本文件并重新加载它。
所以基本上我寻找最优雅和面向 future 的方法来解决这个问题:) 我用的是D2007。
最佳答案
组件名称使用 IsValidIdent
进行验证SysUtils 中的函数,它只是检查第一个字符是字母还是下划线,以及所有后续字符是否是字母数字或下划线。
要创建符合这些规则的字符串,只需删除任何不合格的字符,然后添加一个合格的字符(如果结果以数字开头)。
对于相似的名称,该转换可能会产生相同的结果。如果这不是您想要的,那么您可以在字符串末尾添加一些唯一的内容,例如根据输入字符串计算的校验和或您的部门 ID。
function MakeValidIdent(const s: string): string;
var
len: Integer;
x: Integer;
c: Char;
begin
SetLength(Result, Length(s));
x := 0;
for c in s do
if c in ['A'..'Z', 'a'..'z', '0'..'9', '_'] then begin
Inc(x);
Result[x] := c;
end;
SetLength(Result, x);
if x = 0 then
Result := '_'
else if Result[1] in ['0'..'9'] then
Result := '_' + Result;
// Optional uniqueness protection follows. Choose one.
Result := Result + IntToStr(Checksum(s));
Result := Result + GetDepartment(s).ID;
end;
在 Delphi 2009 及更高版本中,将后两个 in
运算符替换为对 CharInSet
的调用功能。 (Unicode 字符不能很好地与 Delphi 集配合使用。)在 Delphi 8 及更早版本中,将第一个 in
运算符更改为经典的 for
循环并索引到 s
.
关于delphi - 如何清洗/验证字符串以将其分配给组件名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1605588/