Seite 1 von 3

String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 14:07
von Moxl
Hallo liebe Community,

ich habe wiedermal ein Problem bei dem ich nicht weiter komme.
Aber Vielleicht habt ihr ein paar Tipps und Tricks.

Ich habe einen String der z.B. wie folgt aussieht:

Code: Alles auswählen

alben$="American Idiot2004Dookie1994Revolution Radio2016Nimrod1997
Jetzt möchte ich den String gerne auseinander nehmen, sodass ich mehrere Strings mit den einzelnen Alben habe wie z.B.

Code: Alles auswählen

album1$="American Idiot2004"

Code: Alles auswählen

album2$="Dookie1994"

Code: Alles auswählen

album3$="Revolution Radio2016"

Code: Alles auswählen

album4$="Nimrod1997"
So, die Schwierigkeit bei der Sache ist, dass sich der Inhalt des Strings nicht immer gleich ist. Das einzige was immer gleich bleibt
ist, dass am Ende jeden Albens eine vierstellige Jahreszahl steht. (Welche aber auch immer anders ist)

Habt ihr eine Idee wie man den String trennen kann?
Stehe irgendwie voll auf dem Schlauch :freak:

Vielen Dank schonmal im Vorraus :allright:

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 14:13
von RSBasic
Warum ist der String so aufgebaut? Kein Trennzeichen vorhanden? Woher bekommst du den String?
Was du machen kannst ist, in einer Schleife jedes Zeichen zu prüfen, ob es ein Buchstabe oder eine Zahl ist. Wenn das vorherige Zeichen eine Zahl war und das nächste Zeichen ein Buchstabe, dann kannst du abtrennen.
Es gibt bestimmt auch eine RegEx-Lösung.

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 15:11
von Nino
Moxl hat geschrieben:Das einzige was immer gleich bleibt ist, dass am Ende jeden Albens eine vierstellige Jahreszahl steht. (Welche aber auch immer anders ist)
Das lässt sich mit einem Regulären Ausdruck einfach lösen:

Code: Alles auswählen

EnableExplicit

Define alben$, rex.i

alben$ = "American Idiot2004Dookie1994Revolution Radio2016Nimrod1997"

rex = CreateRegularExpression(#PB_Any, ".*?\d{4}")

If ExamineRegularExpression(rex, alben$)
   While NextRegularExpressionMatch(rex)
      Debug RegularExpressionMatchString(rex)
   Wend
EndIf
FreeRegularExpression(rex)

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 15:20
von TroaX
Ich frage mich auch gerade, aus welcher Datenquelle so etwas kommt. Es macht einfach überhaupt keinen auch nur im Ansatz nachvollziehbaren Sinn, Daten auf die Art und Weise abzulegen. Wenn du die Daten selbst auf die Art und Weise ablegst, dann solltest du dir eher darum Gedanken machen, wie du sie besser ablegen kannst. PureBasic unterstützt einige Möglichkeiten, Daten leicht strukturiert abzulegen. Darunter zum einen SQLite, XML und JSON.

Es gibt dafür natürlich auch eine Lösung mit Regulären Ausdrücken. Das müsste jetzt aus dem Kopf so klappen:

Code: Alles auswählen

\D*\d{4}

Code: Alles auswählen

CreateRegularExpression(0, "\D\d{4}")
oder

Code: Alles auswählen

[a-z A-Z]*[0-9]{4}

Code: Alles auswählen

CreateRegularExpression(0, "[a-z A-Z]*[0-9]{4}")
So könnte es gehen:

Code: Alles auswählen

Alben.s = "American Idiot2004Dookie1994Revolution Radio2016Nimrod1997"

If CreateRegularExpression(0, "[a-z A-Z]*[0-9]{4}")
  If ExamineRegularExpression(0, Alben)
    While NextRegularExpressionMatch(0)
      Debug "Album: " + RegularExpressionMatchString(0)
    Wend
  EndIf
Else
  Debug RegularExpressionError()
EndIf
Ausgabe:

Code: Alles auswählen

Album: American Idiot2004
Album: Dookie1994
Album: Revolution Radio2016
Album: Nimrod1997

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 15:32
von Nino
TroaX hat geschrieben:

Code: Alles auswählen

[a-z A-Z]*[0-9]{4}
Das funktioniert nur für das gegebene Beispiel; aber nicht mehr, sobald ein Albumtitel spezielle Zeichen wie Bindestrich, Anführungszeichen etc. enthält.
\D*\d{4} ist schon besser, funktioniert aber ebenso wie der vorige Reguläre Ausdruck nicht mit Albumtiteln, die außer der obligatorischen Jahreszahl am Ende noch andere Ziffern enthälten.

Ich habe oben einen Regulären Ausdruck genannt, der den gegebenen Bedingungen entspricht:
Moxl hat geschrieben:Das einzige was immer gleich bleibt ist, dass am Ende jeden Albens eine vierstellige Jahreszahl steht. (Welche aber auch immer anders ist)

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 15:33
von H.Brill
oder sogar direkt in ein Array :

Code: Alles auswählen

Define alben$, NbFound.l
alben$ = "American Idiot2004Dookie1994Revolution Radio2016Nimrod1997"
If CreateRegularExpression(0, "[a-z,A-Z ]{1,}[0-9]{1,}")
  Dim Result$(0)
  NbFound = ExtractRegularExpression(0, alben$, Result$())
  For k = 0 To NbFound-1
      Debug Result$(k)
    Next
 Else
    Debug RegularExpressionError()
 EndIf
  
PS : auf das Leerzeichen hinter A-Z achten.

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 15:45
von Nino
H.Brill hat geschrieben:PS : auf das Leerzeichen hinter A-Z achten.
Ob mit oder ohne Leerzeichen hinter A-Z: Das funktioniert nicht mehr, sobald ein Albumtitel außer der obligatorischen Jahreszahl am Ende noch andere Ziffern enthält -- oder spezielle Zeichen wie Bindestrich, Anführungszeichen etc.

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 16:36
von ccode_new
Hallo!

Mir gefällt der Zusammenbau der Ausgangszeichenkette überhaupt nicht.

Ich würde dort ein anderes Speicherformat bevorzugen.

Was ist wenn vor der Jahreszahl auch eine Zahl steht und das nachfolgende Album auch wieder mit einer Zahl beginnt ?


Am besten sind auch Alben wie z.B. : "Best of 20.. - 20.."


Dann funktioniert auch der Algo von Nino nicht mehr.

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 17:14
von TroaX
Nino hat geschrieben:Das funktioniert nur für das gegebene Beispiel; aber nicht mehr, sobald ein Albumtitel spezielle Zeichen wie Bindestrich, Anführungszeichen etc. enthält.
\D*\d{4} ist schon besser, funktioniert aber ebenso wie der vorige Reguläre Ausdruck nicht mit Albumtiteln, die außer der obligatorischen Jahreszahl am Ende noch andere Ziffern enthälten.
Das spielt keine Rolle, da bereits die Datenquelle in seiner Struktur völlig inkonsistent ist und es schlicht viel zu umständlich ist, alle theoretisch aufkommenden Situationen abzudecken. Siehe Beitrag von ccode_new.
Da es sich um Jahreszahlen handelt, könnte man es auch so machen:

Code: Alles auswählen

.*?(19\d\d|20\d\d)
Und wenn Alben aus dem jahr 2020 dort gespeichert werden und die Titel auch wieder mit 2 Ziffern anfangen? Ist zwar noch viel unwahrscheinlicher. Aber trotzdem ist eine vernünftige Datenstruktur eben deutlich besser als das ganze mit regulären Ausdrücken zu zerteilen. Noch dazu will sich mir auch nicht erchließen, warum die Jahreszahl hinter dem Album direkt anschließen muss.

Re: String auseinander nehmen [kompliziert]

Verfasst: 26.08.2018 17:23
von Nino
TroaX hat geschrieben:
Nino hat geschrieben:Das funktioniert nur für das gegebene Beispiel; aber nicht mehr, sobald ein Albumtitel spezielle Zeichen wie Bindestrich, Anführungszeichen etc. enthält.
\D*\d{4} ist schon besser, funktioniert aber ebenso wie der vorige Reguläre Ausdruck nicht mit Albumtiteln, die außer der obligatorischen Jahreszahl am Ende noch andere Ziffern enthälten.
Das spielt keine Rolle, da bereits die Datenquelle in seiner Struktur völlig inkonsistent ist und es schlicht viel zu umständlich ist, alle theoretisch aufkommenden Situationen abzudecken.
Das spielt sehr wohl eine Rolle. Es stimmt, dass die Daten in ihrer Struktur nicht so sind, dass eine Auftrennung in jedem denkbaren Fall zuverlässig möglich ist. Das ist allerdings kein Grund dafür, absichtlich einen Regulären Ausdruck zu verwenden, der unnötig oft nicht das gewünschte Ergebnis liefert.