【问题标题】:How to detect if a character from a string is upper or lower case?如何检测字符串中的字符是大写还是小写?
【发布时间】:2011-12-06 01:30:30
【问题描述】:

我正在扩展我的一类用于存储通用大小字符串,以便为用户输入提供更灵活的值。例如,我以前的这个类的版本是严格的,只允许2x3 或9x12 的格式。但现在我正在制作它,以便它可以支持 2 x 3 或 9 X 12 等值,并在值发生更改时自动保持原始用户的格式。

我要弄清楚的真正问题是如何检测字符串中的一个字符是大写还是小写?因为我必须检测区分大小写。如果分隔符是“x”(小写)并且用户在值内输入“X”(大写),并且关闭了区分大小写,我还需要能够找到相反的大小写。

我的意思是,Pos() 函数区分大小写...

【问题讨论】:

    标签: string delphi parsing delphi-7


    【解决方案1】:

    Delphi 7 具有字符串的 UpperCase() 和 LowerCase() 函数。字符也有 UpCase()。

    如果我想在另一个字符串中不区分大小写地搜索子字符串,我这样做:

    if Pos('needle', LowerCase(hayStack)) > 0 then
    

    您只需使用小写字符串文字(或常量)并在搜索之前将小写函数应用于字符串。如果您要进行大量搜索,只需将一次转换为临时变量是有意义的。

    这是你的情况:

    a := '2 x 3';  // Lowercase x
    b := '9 X 12'; // Upper case X
    
    x := Pos('x', LowerCase(a)); // x = 3
    x := Pos('x', LowerCase(b)); // x = 3
    

    要查看一个字符是大写还是小写,只需将其与它的 UpCase 版本进行比较:

    a := 'A';
    b := 'b';
    
    upper := a = UpCase(a); // True
    upper := b = UpCase(b); // False
    

    【讨论】:

    • 伟大的“大海捞针”示例:P,看起来这也是更简单的方法。本例不涉及解析,仅 1) 删除空格,2) 定位分隔符,3) 获取分隔符前后的文本,以及 4) 尝试将左右文本转换为数字。我以前的方法是逐字符循环。
    • 我从 PHP 文档中偷了针/干草堆的类比。在这种情况下,它比 foo/bar 更好。 :)
    【解决方案2】:

    尝试使用这些函数(它们是Character 单元的一部分)

    更新

    对于 delphi 的 ansi 版本,您可以使用 GetStringTypeEx 函数来填充每个 ansi 字符类型信息的列表。然后将每个元素的结果与 $0001(大写)或 $0002(小写)值进行比较。

    uses
      Windows,
      SysUtils;
    
    Var
      LAnsiChars: array [AnsiChar] of Word;
    
    procedure FillCharList;
    var
      lpSrcStr: AnsiChar;
      lpCharType: Word;
    begin
      for lpSrcStr := Low(AnsiChar) to High(AnsiChar) do
      begin
        lpCharType := 0;
        GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, @lpSrcStr, SizeOf(lpSrcStr), lpCharType);
        LAnsiChars[lpSrcStr] := lpCharType;
      end;
    end;
    
    function CharIsLower(const C: AnsiChar): Boolean;
    const
      C1_LOWER  = $0002;
    begin
      Result := (LAnsiChars[C] and C1_LOWER) <> 0;
    end;
    
    function CharIsUpper(const C: AnsiChar): Boolean;
    const
      C1_UPPER  = $0001;
    begin
      Result := (LAnsiChars[C] and C1_UPPER) <> 0;
    end;
    
    begin
      try
        FillCharList;
        Writeln(CharIsUpper('a'));
        Writeln(CharIsUpper('A'));
        Writeln(CharIsLower('a'));
        Writeln(CharIsLower('A'));
      except
        on E:Exception do
          Writeln(E.Classname, ': ', E.Message);
      end;
      Readln;
    end.
    

    【讨论】:

    • Character... 似乎在 Delphi 7 中找不到 - 这是在较新的版本中吗? (我忘了标记它delphi-7)
    • 请始终添加您的 delphi 版本。
    • +1,或者您可以尝试使用IsCharLower 和IsCharUpper 来确定字符大小写,但这取决于区域设置。
    【解决方案3】:
       if myChar in ['A'..'Z'] then
        begin
          // uppercase
        end
       else
          if myChar in ['a'..'z'] then
          begin
            // lowercase
          end
          else
            begin
              // not an alpha char
            end;
    

    ..或 D2009 上..

       if charInSet(myChar,['A'..'Z']) then
       begin
          // uppercase
       end
       else
         if charInSet(myChar,['a'..'z']) then
         begin
           // lowercase
         end
         else
            begin
              // not an alpha char
            end;
    

    【讨论】:

    • 很好的答案,这意味着我必须遍历每个字符并跟踪 if (HasL) and (not HasD) then ... else if (HasL) and (HasD) and (not HasR) then ... 等等......但总的来说我应该这样做:D
    【解决方案4】:

    JCL 在 JclStrings 单元中有用于此的例程,例如 CharIsUpper 和 CharIsLower。应该在 Delphi 7 中工作。

    【讨论】:

      【解决方案5】:

      AnsiPos() 不区分大小写。无论用户使用UpperCase() 和LowerCase() 输入什么,您也可以强制使用大写或小写。

      只是把它扔在那里,因为您可能会发现它比其他(非常好的)答案简单得多。

      【讨论】:

      • 我想过强迫它,但我们的用户社区非常坚持按照他们的方式做事:P
      • 您不必强制输入或存储它的格式,只需在后台使用的格式对值进行操作!
      猜你喜欢
      • 2011-09-15
      • 2020-10-21
      • 2012-01-03
      • 1970-01-01
      • 2010-11-04
      • 2020-04-05
      • 2015-04-23
      • 2018-06-17
      • 1970-01-01
      相关资源
      最近更新 更多