How to detect if a character from a string is upper or lower case?

11,272

Solution 1

Delphi 7 has UpperCase() and LowerCase() functions for strings. There's also UpCase() for characters.

If I want to search for a substring within another string case insensitively, I do this:

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

You simply use lower case string literals (or constants) and apply the lowercase function on the string before the search. If you'll be doing a lot of searches, it makes sense to convert just once into a temp variable.

Here's your case:

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

To see if a character is upper or lower, simply compare it against the UpCase version of it:

a := 'A';
b := 'b';

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

Solution 2

try using these functions (which are part of the Character unit)

UPDATE

For ansi versions of delphi you can use the GetStringTypeEx functions to fill a list with each ansi character type information. and thne compare the result of each element against the $0001(Upper Case) or $0002(Lower Case) values.

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.

Solution 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;

..or D2009 on..

   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;

Solution 4

The JCL has routines for this in the JclStrings unit, eg CharIsUpper and CharIsLower. SHould work in Delphi 7.

Solution 5

AnsiPos() is not case-sensitive. You can also force upper or lower case, irrespective of what the user enters using UpperCase() and LowerCase().

Just throwing this out there since you may find it far more simple than the other (very good) answers.

Share:
11,272
Jerry Dodge
Author by

Jerry Dodge

I'm a Delphi developer. I work for a software company which does solutions for retail management, including inventory, POS, reporting, BI, Tags, and more. It's been in Delphi since Delphi's been around. I am actively in Stack Overflow monitoring the Delphi tag, and looking for those questions I can answer and also contributing my time to keep Stack Overflow in order. I'm not an expert in anything, a jack of all trades rather. But I love to help people when I'm able to. I've known Delphi since about 2007 now, and before that, I had learned VB6. I havn't gone back to VB since I learned Delphi. I also taught myself QBasic and HTML as a kid. It hasn't been until the past 5 years that I've been diving into programming. Since then I've also become vaguely familiar with ASP.NET with C#, as well as some C# windows apps. But I'm not too fond of the whole .NET idea. .NET is good for web platforms and such, but not for win apps. My latest work has been with Delphi 10 Seattle mobile development. I'm still very raw on the subject, but see a huge potential behind it. My strengths: Understanding the bigger picture of projects Writing Custom Classes, Components, and Controls Code organization (within unit or namespace) Writing purely independent classes (as opposed to cross-referencing units or namespaces) User Friendly UI's Developer Friendly Classes Encapsulating layers of business logic My weaknesses: Lower-level coding (such as Assembly) Platform-specific design (using Firemonkey) Web Design It's always nice to know you're able to do something, even if you never use it.

Updated on June 05, 2022

Comments

  • Jerry Dodge
    Jerry Dodge almost 2 years

    I'm expanding a class of mine for storing generic size strings to allow more flexible values for user input. For example, my prior version of this class was strict and allowed only the format of 2x3 or 9x12. But now I'm making it so it can support values such as 2 x 3 or 9 X 12 and automatically maintain the original user's formatting if the values get changed.

    The real question I'm trying to figure out is just how to detect if one character from a string is either upper or lower case? Because I have to detect case sensitivity. If the deliminator is 'x' (lowercase) and the user inputs 'X' (uppercase) inside the value, and case sensitivity is turned off, I need to be able to find the opposite-case as well.

    I mean, the Pos() function is case sensitive...

  • Jerry Dodge
    Jerry Dodge over 12 years
    Character... Doesn't seem to be found in Delphi 7 - is this in a newer version? (I forgot to tag it delphi-7)
  • RRUZ
    RRUZ over 12 years
    Please add always your delphi version.
  • Jerry Dodge
    Jerry Dodge over 12 years
    Good answer, and it means I have to loop through each character and keep track of if (HasL) and (not HasD) then ... else if (HasL) and (HasD) and (not HasR) then ... and so on... But that's overall how I should do it anyway :D
  • Jerry Dodge
    Jerry Dodge over 12 years
    I thought of forcing it, but our user community is very insistent on doing things their way :P
  • Jerry Dodge
    Jerry Dodge over 12 years
    Great "finding the needle in the haystack" example :P and it looks like that's also the much easier approach to doing this too. No parsing involved in this case, just 1) Remove spaces, 2) Locate deliminator, 3) Get text before and after deliminator, and 4) Try to convert left and right text into numbers. My previous approach was looping char by char.
  • Marcus Adams
    Marcus Adams over 12 years
    I stole the needle/haystack analogy from PHP docs. It's better than foo/bar in this case. :)
  • LaKraven
    LaKraven over 12 years
    You don't have to force the format it's entered or stored in, only the format used behind the scenes to operate on the values!
  • TLama
    TLama over 12 years
    +1, Or you might try to use IsCharLower and IsCharUpper for determining the char case but this is based on the locale settings.