简体   繁体   English

Delphi - 循环遍历字符串

[英]Delphi - Loop through the String

I'm trying to find out if String is "mnemonic type"... My mnemonic type consists of letters from 'a' to 'z' and from 'A' to 'Z', digits from '0' to '9', and additionaly '_'. 我试图找出String是否是“助记符类型”...我的助记符类型包括从'a'到'z'和从'A'到'Z'的字母,从'0'到'9'的数字,另外'_'。 I build code like below. 我构建如下代码。 It should result with True if given string match my mnemonic pattern otherwise False: 如果给定字符串匹配我的助记符模式,它应该为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;

This code always results with False. 此代码始终以False结果。

I'm assuming that since you tagged the question XE5, and used zero-based indexing, that your strings are zero-based. 我假设,因为你标记了问题XE5,并使用了从零开始的索引,你的字符串是从零开始的。 But perhaps that assumptions was mistaken. 但也许这些假设是错误的。

Your logic is fine, although it is rather hard to read. 你的逻辑很好,虽然它很难阅读。 The code in the question is already doing what you intend. 问题中的代码已经在做你想要的了。 At least the if statement does indeed perform the test that you intend. 至少if语句确实执行了您想要的测试。

Let's just re-write your code to make it easier to understand. 让我们重新编写代码,以便更容易理解。 I'm going to lay it our differently, and use a local loop variable to represent each character: 我将以不同的方式放置它,并使用本地循环变量来表示每个字符:

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;

When written like that I'm sure that you will agree that it performs the test that you intend. 如果这样写,我相信你会同意它执行你想要的测试。

To make the code easier to understand however, I would write an IsValidIdentifierChar function: 但是为了使代码更容易理解,我会编写一个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;

As @TLama says, you can write IsValidIdentifierChar more concisely using CharInSet : 正如@TLama所说,你可以使用CharInSet更简洁地编写IsValidIdentifierChar

function IsValidIdentifierChar(C: Char): Boolean;
begin
  Result := CharInSet(C, ['0'..'9', 'a'..'z', 'A'..'Z', '_']);
end;

Then you can build your loop on top of this function: 然后你可以在这个函数的基础上构建你的循环:

TRes := True;
for C in AString do
  if not IsValidIdentifierChar(C) do 
  begin
    TRes := False;
    break;
  end;

String type is 1-based. 字符串类型是从1开始的。 dynamic Arrays are 0-based. 动态数组是从0开始的。 Better use for ... in so you are safe for future Delphi's. 更好地用于......所以你对未来的Delphi是安全的。

Testing for ranges of possible character values can be done more efficiently (and more conciece) is CharInSet. 可以更有效地(并且更加连贯)地测试可能的字符值的范围是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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM