StringEntry - Erweiterung von StringField

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
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

StringEntry - Erweiterung von StringField

Beitrag von STARGÅTE »

Tachchen,

weil ich es brauchte habe ich mal eine Erweiterung von StringField geschrieben.

StringEntry
- Auslesen von numerischen oder assoziativen (oder gemischten) Listen im String-Format
- Auslesen von Unterlisten von Listen im String-Format mittels Index-Pfad
- Alle Zeichen in Indexnamen und Werten erlaubt (außer den 4 MetaZeichen)
- Leerzeichen am Rand werden abgeschnitten!

StringEntry(String$, IndexPath$, MetaChars$="={},", DefaultValue$="")
- String$ - Irgendeine Zeichenkette mit gültigem Syntax
- IndexPath$ - Index-Pfad zu einem Feld Indizes getrennt mit \
- MetaChars$ - Benutzerdefinierte Meta-Zeichen für
  * Zuweisung von Werten zu Indizes "="
  * Öffnen und schließen einer Liste "{}"
  * Feld-Trennzeichen ","
- DefaultValue$ - Rückgabewert bei nicht auffindbarem Index

ein leerer oder "0" Index gibt den ganze String zurück


Code:

Code: Alles auswählen

Structure CharacterArray
  c.c[0]
EndStructure

Procedure.s StringEntry(String$, IndexPath$, MetaChars$="={},", DefaultValue$="")
  Protected *Current.Character   = @String$-1
  Protected *Left.Character      = @String$
  Protected *Center.Character    = @String$
  Protected *Meta.CharacterArray = @MetaChars$
  Protected Level = 0
  Protected Key$ = Trim(IndexPath$) , SubIndexPath$ = ""
  Protected Key, Field = 1, Value$
  Protected SubKey = FindString(IndexPath$, "\", 1) 
  If SubKey
    Key$ = Trim(Left(IndexPath$, SubKey-1))
    SubIndexPath$ = Mid(IndexPath$, SubKey+1)
  EndIf
  If Key$ = ""
    ProcedureReturn String$
  Else
    Key = Val(Key$)
  EndIf
  Repeat
    *Current + SizeOf(Character)
    Select *Current\c
      Case *Meta\c[0]
        If Not Level
          *Center = *Current
        EndIf
      Case *Meta\c[1]
        Level + 1
      Case *Meta\c[2]
        Level - 1
      Case *Meta\c[3], 0
        If Not Level
          Field$ = Trim(PeekS(*Left, *Center-*Left))
          If Field = Key Or Field$ = Key$
            If Not Field$
              Value$ = Trim(PeekS(*Center, *Current-*Center))
            Else
              Value$ = Trim(PeekS(*Center+1, *Current-*Center-1))
            EndIf
            If SubKey
              If Left(Value$, 1) = Chr(*Meta\c[1])
                Value$ = Trim(Mid(Value$, 2, Len(Value$)-2))
              EndIf
              ProcedureReturn StringEntry(Value$, SubIndexPath$, MetaChars$, DefaultValue$)
            Else
              ProcedureReturn Value$
            EndIf
          EndIf
          *Left = *Current+1
          *Center = *Left
          Field + 1
        EndIf
    EndSelect
  Until Not *Current\c
  ProcedureReturn DefaultValue$
EndProcedure
Hier ein komplexes Beispiel:

Code: Alles auswählen

String$ = " Spieler=5, Name=Max, Position={x=10.5,y=7.2}, Waffe={{Messer, 1},{Pfeil, 150}} "
StringEntry als StringField benutzen:

Code: Alles auswählen

Debug #DQUOTE$+StringEntry(String$, "2")+#DQUOTE$ ; Liefert "Max"
Debug #DQUOTE$+StringEntry(String$, "4")+#DQUOTE$ ; Liefert "{{Messer, 1},{Pfeil, 150}}"
Zugriff auf die SchlüsselIndizes:

Code: Alles auswählen

Debug #DQUOTE$+StringEntry(String$, "Spieler")+#DQUOTE$ ; Liefert "5"
Debug #DQUOTE$+StringEntry(String$, "Position")+#DQUOTE$ ; Liefert "{x=10.5,y=7.2}"
Zugriff auf Elemente einer Unterliste:

Code: Alles auswählen

Debug #DQUOTE$+StringEntry(String$, "Position\1")+#DQUOTE$ ; Liefert "10.5"
Debug #DQUOTE$+StringEntry(String$, "Position\y")+#DQUOTE$ ; Liefert "7.2"
Debug #DQUOTE$+StringEntry(String$, "Waffe\2\2")+#DQUOTE$ ; Liefert "150"
Stückweise zerkleinern:

Code: Alles auswählen

SubString$ = StringEntry(String$, "Waffe\") ; der \ am Ende bewirkt das die außere Klammer entfernt wird
Debug #DQUOTE$+SubString$+#DQUOTE$ ; Liefert "{Messer, 1},{Pfeil, 150}"
Debug #DQUOTE$+StringEntry(SubString$, "2\1")+#DQUOTE$ ; Liefert "Pfeil"
Zuletzt geändert von STARGÅTE am 07.01.2010 20:27, insgesamt 1-mal geändert.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
HeX0R
Beiträge: 3054
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: StringEntry - Erweiterung von StringField

Beitrag von HeX0R »

Also eigentlich wäre doch für diese Aufgabenstellung XML perfekt, oder nicht?
Hast du jetzt einfach zu schnell was zusammengebastelt, ohne länger drüber nachzudenken, oder was ist der wirkliche Vorteil?

Ich meine xml ist ziemlich träge, o.k., aber so wie das aussieht willst du auch nur Levelinfos o.ä. vor einem Spiel laden, da wäre die Ladegeschwindigkeit doch auch egal.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: StringEntry - Erweiterung von StringField

Beitrag von STARGÅTE »

Was der Benutzer mit StringEntry anfängt soll er selber entscheiden ...

klar sind Komplexe Baumstrukturen Sache von XML ...
Nur ich möchte ungern für kleine verschachtelte Listen mein Programm mit XML belasten:
Wichtig: Die expat Lizenz erfordert, dass eine Copyright-Notiz und der Lizenz-Text selbst in jede Software integriert werden, welche den Parser beinhalten.
Schließlich will ich nicht solche Probleme haben wie jetzt Microsoft
Microsoft verliert Rechtsstreit um Word

Bei XML muss ich mich außerdem strickt an einen Syntax halten ... bei StringEntry (auch wenns noch nicht perfekt ist)
kann ich selber entscheiden, wie meine Daten verpackt sind.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten