Erweitertes LCase und UCase (mit Sonderzeichen)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Erweitertes LCase und UCase (mit Sonderzeichen)

Beitrag von NicTheQuick »

Beide Funktionen überschreiben per Macros die normalen LCase()- und
UCase-Funktionen und funktionieren wie folgt:
Beim ersten Aufruf wird ein Array erstellt, in dem jedem Zeichen (ASCII 0
bis 255) seine kleinere bzw. größere Version zugeordnet wird. Das Array
bleibt wegen "Static" im Speicher und muss am dem zweiten Aufruf der
Funktion nicht wieder neu erzeugt werden. Somit sollte die Funktion schnell
genug sein.

Das Umformen hab ich anhand der ASCII-Tabelle in der PB-Hilfe (F1)
vorgenommen. Die Funktionen unterstützen auch Unicode.

Ich denke, dass es mit dem Array die effizienteste Art ist. Wer einen
besseren Vorschlag hat (außer API), bitte melden. :)

Code: Alles auswählen

;info: advanced LCase and UCase

Procedure.s _LCase(String.s)
  Static first.l = 0, Dim Chars.c(255)
  Protected *c.Character, a.l
  
  If first = 0
    For a = 0 To 255
      Select a
        Case 65 To 90
          Chars(a) = a + 32
        Case 138, 140, 142
          Chars(a) = a + 16
        Case 159
          Chars(a) = 255
        Case 192 To 214
          Chars(a) = a + 32
        Case 216 To 222
          Chars(a) = a + 32
        Default
          Chars(a) = a
      EndSelect
    Next
    first = 1
  EndIf
  
  *c = @String
  While *c\c
    If *c\c <= 255
      *c\c = Chars(*c\c)
    EndIf
    *c + SizeOf(Character)
  Wend
  
  ProcedureReturn String
EndProcedure
Macro LCase(String) : _LCase(String) : EndMacro

Procedure.s _UCase(String.s)
  Static first.l = 0, Dim Chars.c(255)
  Protected *c.Character, a.l
  
  If first = 0
    For a = 0 To 255
      Select a
        Case 97 To 122
          Chars(a) = a - 32
        Case 154, 156, 158
          Chars(a) = a - 16
        Case 255
          Chars(a) = 159
        Case 224 To 246
          Chars(a) = a - 32
        Case 248 To 254
          Chars(a) = a - 32
        Default
          Chars(a) = a
      EndSelect
    Next
    first = 1
  EndIf
  
  *c = @String
  While *c\c
    If *c\c <= 255
      *c\c = Chars(*c\c)
    EndIf
    *c + SizeOf(Character)
  Wend
  
  ProcedureReturn String
EndProcedure
Macro UCase(String) : _UCase(String) : EndMacro
Zuletzt geändert von NicTheQuick am 12.10.2006 11:40, insgesamt 2-mal geändert.
Little John

Re: Erweitertes LCase und RCase (mit Sonderzeichen)

Beitrag von Little John »

NicTheQuick hat geschrieben:Die Funktionen unterstützen auch Unicode.
Ja, aber nur ansatzweise. Es werden ja nur die Zeichen von 0-255 unterstützt, Unicode enthält aber viel mehr Zeichen.

Gruß, Little John
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Es werden ja nur die Zeichen von 0-255 unterstützt, Unicode enthält aber viel mehr Zeichen.

stimmt. da müsste man halt das array noch erheblich erweitern.
inwiefern das dann noch sinnvoll ist, ist die weitere frage.
Zeichen, bei denen überhaupt eine groß/klein-schreibung möglich ist,
sind anscheinend über einen weiten coderaum verstreut.
so ist ỹ mit 1EF9 das höchste was ich in Arial gefunden habe,
was keinesfalls bedeutet, dass es 7929 groß- und kleinbuchstaben gäbe.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

schmuddel im titel: nicht Left/Right, sondern Low/Upper..Case :wink:
my pb stuff..
Bild..jedenfalls war das mal so.
Little John

Beitrag von Little John »

Ich glaube man kann froh sein, wenn andere Leute schon die Arbeit erledigt haben, :) und Groß-/Kleinkonvertierung auch für Unicode vom Betriebssystem unterstützt wird (was zumindest für Windows NT/2000/XP zutrifft).

In jedem Fall sollten in Nics Code die beiden While-Schleifen verändert werden, um einen "Array index out of bounds"-Fehler zu vermeiden:

Code: Alles auswählen

While *c\c
   If *c\c <= 255
      *c\c = Chars(*c\c)
   EndIf
   *c + SizeOf(Character)
Wend
Gruß, Little John
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@#Null:
Den Fehler mache ich andauernd. <) Hab's jetzt aber geändert.

@Little John:
Danke für den Hinweis! Hab es jetzt geändert wie du es vorgeschlagen hast.
:allright:
Antworten