我试图找出String是否是“助记符类型”... 我的助记符类型包括从'a'到'z'和从'A'到'Z'的字母,从'0'到'9'的数字,以及另外的'_'。 我构建如下代码。如果给定的字符串匹配我的助记符模式,则应该为True,否则为False:
TRes := True;
for I := 0 to (AString.Length - 1) do
begin
if not ((('0' <= AString[I]) and (AString[I] <= '9'))
or (('a' <= AString[I]) and (AString[I] <= 'z'))
or (('A' <= AString[I]) and (AString[I] <= 'Z'))
or (AString[I] = '_')) then
TRes := False;
end;
此代码始终以False结果。
答案 0 :(得分:10)
我假设您已经标记了问题XE5,并使用了从零开始的索引,因此您的字符串是从零开始的。但也许这些假设是错误的。
你的逻辑很好,虽然它很难阅读。问题中的代码已经在做你想要的了。至少if
语句确实执行了您想要的测试。
让我们重新编写您的代码,以便更容易理解。我将以不同的方式对它进行布局,并使用局部循环变量来表示每个字符:
for C in AString do
begin
if not (
(('0' <= C) and (C <= '9')) // C is in range 0..9
or (('a' <= C) and (C <= 'z')) // C is in range a..z
or (('A' <= C) and (C <= 'Z')) // C is in range A..Z
or (C = '_') // C is _
) then
TRes := False;
end;
当这样写的时候,我确信你会同意它执行你想要的测试。
为了使代码更容易理解,我会写一个IsValidIdentifierChar
函数:
function IsValidIdentifierChar(C: Char): Boolean;
begin
Result := ((C >= '0') and (C <= '9'))
or ((C >= 'A') and (C <= 'Z'))
or ((C >= 'a') and (C <= 'z'))
or (C = '_');
end;
正如@TLama所说,您可以使用IsValidIdentifierChar
更简洁地撰写CharInSet
:
function IsValidIdentifierChar(C: Char): Boolean;
begin
Result := CharInSet(C, ['0'..'9', 'a'..'z', 'A'..'Z', '_']);
end;
然后你可以在这个函数之上构建你的循环:
TRes := True;
for C in AString do
if not IsValidIdentifierChar(C) do
begin
TRes := False;
break;
end;
答案 1 :(得分:5)
字符串类型是从1开始的。动态数组是从0开始的。更好地用于......因此对未来的Delphi来说是安全的。
可以更有效地测试可能的字符值范围(并且更加衔接)是CharInSet。
function IsMnemonic( AString: string ): Boolean;
var
Ch: Char;
begin
for Ch in AString do
if not CharInSet( Ch, [ '_', '0'..'9', 'A'..'Z', 'a'..'z' ] ) then
Exit( False );
Result := True;
end;