【问题标题】:How to get the first element in a string?如何获取字符串中的第一个元素?
【发布时间】:2015-06-17 15:44:16
【问题描述】:

我正在尝试找出一种方法来检查字符串的第一个元素是否是数字。

if not(myString[0] in [0..9]) then //Do something

问题是我收到错误“无法访问元素 0 - 使用 'Length' 或 'SetLength”

从我的类似 C 的经验中我想到了另一种方法 - 将字符串的第一个元素转换为 char 并检查 char,但编译错误没有区别。

if not(char(myString[0]) in [0..9]) then //Do something

我该如何完成?

【问题讨论】:

  • 顺便说一句:表达式 myString[1] 的返回类型已经是一个 Char,所以在这里进行显式转换没有任何意义

标签: delphi string


【解决方案1】:

字符串是从 1 开始的:

if not (myString[1] in ['0'..'9']) then // Do something

【讨论】:

  • 现在只有一个问题“不兼容的类型 - 字符串和整数”。如果我使用 StrToInt 并且字符串不是整数,那么将引发异常并且所有检查都是无用的。你能建议一个更好的方法吗?顺便说一下+1。 :)
  • 再看 TOndrej 的代码:'0'..'9' 周围应该有单引号
  • 在现代版本的 Delphi 中,字符串从 1 开始仅适用于 Windows 平台,对于移动平台,字符串从 0 开始。这意味着建议的代码仅与 Windows 平台兼容。
【解决方案2】:

Pascal 和 Delphi 从 1 开始索引字符串。这是从零字节包含长度,而接下来的 255(索引 1 到 255)包含实际字符的时代的遗留物。 Joel Spolsky 写了一篇关于字符串问题的不错的文章:
http://www.joelonsoftware.com/articles/fog0000000319.html

【讨论】:

  • “Spolsky”文章讨论了在没有任何编译器支持的情况下在 C 中实现 Pascal 字符串。这些问题与支持它的语言无关。
  • @Marco van de Voort:恐怕你完全错过了 Joel 文章的重点。
【解决方案3】:

Delphi 字符串使用从 1 开始的索引,因此只需重写为

if not(myString[1] in ['0'..'9']) then //Do something

还要注意 0..9 周围的引号,否则您会将字符与整数进行比较。

【讨论】:

    【解决方案4】:

    我们应该记住一些事情:

    1. Delphi 中的字符串对于移动平台从 0 开始,对于 Windows 从 1 开始。
    2. 旧版本的 Delphi 中的字符串是 AnsiString(每个字符 1 个字节)和新版本中的 WideString(每个字符 2 个字节)。
    3. Delphi 支持AnsiChar 的集合,但不支持WideChar 的集合。

    所以如果我们想写一个兼容所有版本的Delphi的代码,那么它应该是这样的:

    if (myString[Low(myString)]>='0') and (myString[Low(myString)]<='9') then
      // Do something
    

    【讨论】:

      【解决方案5】:

      if not(myString[0] in [0..9]) then //Do something

      如果您使用的是 Delphi 2009,Character.pas 中的 TCharacter 类具有 IsDigit 之类的函数来帮助简化此类操作。

      当然,一旦您修复了索引。 :)

      【讨论】:

      • 不需要强制转换为 Char(),因为字符串由字符组成,可以直接访问。此外,无论如何,您的比较都是错误的,因为 Char('0') 是十进制 48(十六进制 30),因此不会介于 0 和 9 之间。
      【解决方案6】:

      随着 Delphi 移动代码的后期更新,底部字符串索引从 0 更改为 1。当您编译较旧的程序时,它们使用 0 起始索引正确编译和运行。使用后来的 IDE 创建的程序会产生错误。当你有混合物时,生活就会变得复杂!

      如果能够使用较旧的程序并告诉 IDE 您希望它更新到最新版本会很好(也许这会解决其他问题,例如当您接听电话时字体被打乱!)但它会保持一致!

      【讨论】:

        【解决方案7】:

        最简单的方法是检查string的第一个字符是否为整数,然后dispatch:

        var
          iResult : integer;
        begin
          if TryStrToInt( mySTring[1], iResult) then
            begin
              // handle number logic here iResult = number
            end
          else
            begin
              // handle non number logic here
            end;
        end;    
        

        【讨论】:

        • 不,我认为这根本不是最简单的方法。约翰实际上有正确的想法,但在黑暗中摸索正确的语法。
        • 是的,但如果你想对值进行操作,则需要使用 StrtoInt。如果您使用 TryStrToInt,您不仅可以检查它是否是一个数字,然后您就可以使用该数字。
        【解决方案8】:

        我使用一个实用函数来测试整个字符串:

        function IsNumeric(const Value: string): Boolean;
        var
          i: Integer;
        begin
          Result := True;
          for i := 1 to Length(Value) do
            if not (Value[i] in ['0'..'9','.','+','-']) then
            begin
              Result := False;
              Break;
            end;
        end;
        

        以上代码适用于2007年之前的Delphi版本。在2007年和2009年,您可以将整数变量i更改为字符c,并在Value中使用for c。

        要仅测试整数,请删除“.”从要测试的字符集中。

        【讨论】:

          【解决方案9】:

          这是不正确的。 ISO 字符串和旧的 Pascal 字符串也是从一个开始的。这只是一个一般约定,并且 afaik s[0] 的东西是空缺的结果,并且在 UCSD 字节码解释器中编码很便宜。但最后一点是在我之前,所以只是我的猜测。

          这是由于 Pascal 具有任意上限和下限的能力,这为访问数组提供了更多的类型安全性。

          真正古老的 Pascal 弦(直到八十年代初)弦甚至比 C 弦更糟糕。使用了多种约定,但都基于静态数组(如早期的 C),但它们通常是用空格填充的,所以你从末尾扫描到空格结束。

          (删除了遗留标签,因为基于 1 不是遗留标签。访问 s[0] 作为长度是遗留标签,但这不是问题所在)

          【讨论】:

            【解决方案10】:
            Foreach element in strName
              if not element in [0-9] then
                 do something 
              else
                element is a digit
            end if
            

            不要忘记数字之间的引号。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-12-31
              • 1970-01-01
              • 2013-06-12
              • 1970-01-01
              • 1970-01-01
              • 2021-04-07
              • 1970-01-01
              相关资源
              最近更新 更多