String Parsen und auf eigenes Muster anwenden (kein Regex)

w00t

Aktives Mitglied
Also ....

Ich lese eine Liste von Strings ein und vergleiche diese Miteinander.
Beispiel:
  1. AA.A.A001.BBB.ab.cde
  2. AA.A.A002.CC.ab.cde
  3. AA.A.A003.DDDD.ab.cde


Daraus baue ich mir eine ArrayList mit einer erweiterten Version von Character (CharacterEx). Dies sind dann so aus:
Code:
AA.A.A00X.Y.ab.cde

Das X bedeutet das hier eine Zahl steht, die Variabel ist.
Das Y bedeutet das hier ein String steht, der Variabel ist.

Meine Klasse CharacterEx speichert die Position innerhalb des Originalstrings sowie den Typen.
Typen:
  1. Unbekannt
  2. String
  3. Integer


Um den Variablen String in der Mitte zu finden, gehe ich meine Ausgangsstrings von vorne und von hinten durch und vergleiche. Zum Schluss werden die Ergebnisse zusammengefasst.

Nun hat man die Möglichkeit ein Muster festzulegen. Hierfür folgende Schreibweise:
Code:
[HS].[HIS].[S].[D]
[HS] = Fester String (kann alles enthalten, auch zahlen)
[HIS] = Fester String, der VARIABLE! Zahlen enthalten kann
[S] = Variabler String
[D] = Dummy (alles andere)

Nun muss das ganze auf den String gematcht werden, so das folgendes Ergebnis herauskommt:
Code:
AA.A.A00X.Y.ab.cde
Code:
[HS] = AA.A
.
[HIS] = A00X
.
[S] = Y
.
[D] = ab.cde

Nun gäbe es eine Klasse, ich nenne sie einmal StringEx, die die Informationen speichert, und dies alles für jedes Element in der Liste:
List:
Code:
-------------
Type: [HS]
Value: AA.A
Position: 0, 3
Index: 0
Alias: [HS|1]
-------------
Type: divider
Value: .
Position: 4,4
Index: 1
-------------
Type: [HIS]
Value: A00X
Position: 5,9
Index: 2
Alias: [HIS|1]
-------------
Type: divider
Value: .
Position: 10,10
Index: 3
-------------
Type: [S]
Value: Y
Position: 11,11
Index: 4
Alias: [S|1]
-------------
Type: divider
Value: .
Position: 12,12
Index: 5
-------------
Type: [D]
Value: ab.cde
Position: 13,18
Index: 6
Alias: [D|1]
-------------

Sollte ein Element öfter vorkommen (z.B. [HIS], wäre der Alias für das zweite Element [HIS|2]).

Meine Idee war nun eine Art Parser zu schreiben, der ähnlich wie Regex funktioniert, nur halt auf meinen Fall anwendbar ist. Allerdings fehlt mir gerade die Vorstellung wie ich das angehen soll.

Aktuell spiele ich mit folgendem Gedanken:
Das Ursprungsmuster in eine Map packen:
Code:
map.put("[HS]")
map.put(".")
...
Dann gehe ich meine Liste von CharacterEx durch und .... tja. Hier fehlt mir dann irgendwie eine Idee wie ich das umsetzten kann. Es ist auch NICHT zwingend erforderlich, das zwischen den einzelnen Mustern ein "." ist. es könnte auch:
Code:
[HS][HIS][S][D]
sein, der dann auf folgendes matcht, das ist also variabel:
Code:
[HS] = AA.A.
[HIS] = A00X.
[S] = Y
[D] = .ab.cde

Was ich hier NICHT erwarte: Eine fertige Lösung von jemandem. FALLS es so etwas in der Art allerdings schon gibt, gerne her damit! Auch Codebeispiele usw. wären hilfreich. Aber im Endeffekt freue ich mich über Ideen die mich weiter bringen, Stichwörter usw.
 
Leider kann ich meinen Beitrag nicht mehr bearbeiten (kann ein Mod meine Beiträge evtl zusammenführen?).

Auf tutorials.de hat nun jemand ein paar Sachen gefragt. Daraufhin habe ich geantwortet was ich überhaupt vor habe:

Vielleicht sollte ich einmal ergänzen was mein Ziel ist.

Eigentlich geht es um Dateinamen die Serien abbilden.
Beispiel (gutes Beispiel, weil es eig alles enthält):
2.Broke.Girls.S04E01.Das.Reality.Problem.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E02.Der.Bio.Club.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E03.Von.Fischen.und.Baeren.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E04.Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP

Das Ziel ist es, die Dateien (halb-)automatisch umzubenennen. Halb deshalb, da man ja ein Muster ([HIS [S ]usw.) angeben muss.
Ergebnis hier wäre also:
2.Broke.Girls.S04E0*.*.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
(Als Platzhalter diesmal *, anstatt X und Y, zur besseren Lesbarkei.)
Damit ist das geplante Ergebnis bei dem Muster [HS].[HIS].[S ].[D]:
    • [HS] = 2.Broke.Girls
    • .
    • [HIS] = S04E0*
    • .
    • [S ] = *
    • .
    • [D] = GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
Nun ist geplant das man ein ein Eingangs- und ein Ausgangsmuster hat:
Eingangsmuster: [HS].[HIS].[S ].[D]
Ausgangsmuster: [HS] - [HIS] - [S ]
Damit wäre dann eine Halbautomatische Umbenennung möglich:
2.Broke.Girls - S04E0* - *
Was dann folgendes ergeben würde:
2.Broke.Girls - S04E01 - Das.Reality.Problem
2.Broke.Girls - S04E02 - Der.Bio.Club


Btw... den Code den ich bisher habe ist hier zu sehen:
jsrenamer at PatternTest - GitHub

Sollten nun noch Fragen offen sein, her damit 😉
Ich komm einfach nicht sinnvoll weiter. Gedankensperre^^
 
Zuletzt bearbeitet:
Hab mir jetzt nicht angesehen was du schon hast, aber das hier dürfte so in die Richtung gehen:

Java:
String s = "2.Broke.Girls.S01E04.Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP";

String constant = ".GERMAN.DL.DUBBED.720p.WebHD.x264-TVP";
Pattern p = Pattern.compile("\\.[Ss][0-9]{1,3}[Ee][0-9]{1,3}\\.");
Matcher m = p.matcher(s);

if(m.find())
{
	String show = s.substring(0, m.start());
	String rest = s.substring(m.end(), s.length());
	String title = rest.substring(0, rest.indexOf(constant));
	String group = m.group();
	String seasonEpisode = group.substring(1, group.length() - 1);
	
	System.out.println(show + " - " + seasonEpisode + " - " + title);
}

Das setzt natürlich vorraus, dass das "constant" wirklich konstant ist. Sonst lässt sich einfach nicht feststellen was noch zum Titel gehört und was nicht...
 
Das setzt natürlich vorraus, dass das "constant" wirklich konstant ist. Sonst lässt sich einfach nicht feststellen was noch zum Titel gehört und was nicht...

Genau das ist ja auch das Problem ;-)
Deshalb danke ich Dir für Deinen Vorschlag, doch das es immer so Identisch ist, ist halt leider nicht gegeben. Ein Regex der das so auseinander nimmt ist für mich leider nicht - in der aktuellen Form - möglich. Sonst wäre das auch von mir meine Lösung gewesen.
 
Dann würde ich das schon fast als unlösbar beschreiben. Es ist einfach nicht möglich zu wissen was Titel ist und was zum Zusatz gehört. Gibt es denn gar keine Gemeinsamkeiten im Titelzusatz? z.B. das .GERMAN? Oder falls es auch .ENGLISH gibt könnte man nach einem '.' gefolgt von mindestens zwei Großbuchstaben schauen... Mehr fällt mir nicht ein.
 
Es könnten theoretisch auch andere Strings sein.

2.Broke.Girls.S04E0*.*.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
Mit Regex wäre das ja kein Problem.

Für den ersten Teil:
(.*?)\.S04E0*
Für den zweiten Teil (vorheriger Teil wird abgeschnitten):
(.*?)\..*
Für den dritten Teil (vorheriger Teil wird abgeschnitten):
(\*)\..*
Für den vierten Teil (vorheriger Teil wird abgeschnitten):
.*

Er müsste ja "nur" anhand meiner Liste den Regex erstellen wenn man das über Regex machen würde. Oder einen eigenen Regexparser erstellen der halt kein String bekommt, sondern meine Char-Listen. Quasi eine eigene Regex Engine - angepasst an meinen Fall.

*grübel*
 
Kann dir da ehrlich gesagt nicht folgen.

Ich versuche halt solche Art von Programmen nach dem zu programmieren, wie ich als Mensch vorgehe. Und so weiss ich, daß bei:
".....Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED......" der Titel der Folge nach "Fahrrad" aufhört. Aber wie soll der Rechner das wissen? Der braucht irgendwas konstantes. Wenn der Zusatz eben nicht konstant ist, sehe ich keine Möglichkeit. Und wie gesagt verstehe ich deine Idee mit einer "eigenen Regex Engine" nicht. Denn auch dabei kannst du dich ja auf keine Regel festlegen (weil es eben beim Titel mit Zusatz nichts konstantes gibt). Du hast im diesem Teil ja nur Buchstaben (groß/klein) und Punkte "."
 
Kann dir da ehrlich gesagt nicht folgen.

Ich versuche halt solche Art von Programmen nach dem zu programmieren, wie ich als Mensch vorgehe. Und so weiss ich, daß bei:
".....Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED......" der Titel der Folge nach "Fahrrad" aufhört.
Genau so versuche ich das im normalfall auch. Hier ist es nur sehr komplex und mit einem einzigen String lässt sich das auch für den PC nicht sagen. Aber hat man 2 und mehr Strings, dann sieht das schon anders aus.

Aber wie soll der Rechner das wissen? Der braucht irgendwas konstantes. Wenn der Zusatz eben nicht konstant ist, sehe ich keine Möglichkeit. Und wie gesagt verstehe ich deine Idee mit einer "eigenen Regex Engine" nicht. Denn auch dabei kannst du dich ja auf keine Regel festlegen (weil es eben beim Titel mit Zusatz nichts konstantes gibt). Du hast im diesem Teil ja nur Buchstaben (groß/klein) und Punkte "."

Du scheinst meinen Text nicht ganz gelesen zu haben.

Ich habe ja nicht nur EINEN String, ich habe eine Liste (z.B.):
2.Broke.Girls.S04E01.Das.Reality.Problem.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E02.Der.Bio.Club.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E03.Von.Fischen.und.Baeren.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
2.Broke.Girls.S04E04.Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
Hieraus ergibt sich ja folgendes.
1. Anfang immer identisch:
2.Broke.Girls.S04E0
2. Es folgt eine Variable Zahl:
(Die Zahl zur Episode: S04E0X)
3. Es folgt ein Variabler Teil:
Der Episodentitel
4. Es folgt etwas statisches:
.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP



Ich habe eine Liste von Objekten, die jeden Buchstaben abdecken und spezifizieren. Heißt:
Ist es ein variabler Buchstabe, oder ist er fest? Ist es eine Zahl, oder ein Zeichen?

Mein Ansatz mit einer eigenen Regex Engine (gedanklich):
Ich weiß von jedem Zeichen also nun was er enthält und ob er variabel ist, oder nicht.
Wäre das - so wie es ist - mit Regex auslesbar, müsste ich ein Regex-Muster schreiben dass das abbildet:
[HS].[HIS]..[D]

Der String müsste nun darauf gematcht werden. Einmal in Worten:
Nimm jedes feste Zeichen, bis zu der Stelle, wo ein Punkt (.) folgt, auf dem ein Fester Text mit Variabler Zahl folgt (.[HIS]).
Vergleichbar mit:
(.*?)\.(?=([0-9a-zA-Z]+?)\.) (funktioniert natürlich nicht genau so)
Auf den festen String mit Variabler Zahl, folgt dann ein PUNKT und daraufhin ein Variabler String. Darauf folgt ein PUNKT und dann ein fester String.


Nur zum Verständnis:
Wenn man nun folgendes machen würde:
Schau mal in meinen ersten Post, dort habe ich die Strings zusammengefasst und das Endergebnis sieht ja so aus:
AA.A.A00X.Y.ab.cde

Wobei X und Y variable Werte sind (X eine Variable Zahl). Übernehmen wir das jetzt einmal für unseren echten String:
2.Broke.Girls.S04E01.Das.Reality.Problem.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP

dieser würde - wenn er mit den anderen verglichen würde, so aussehen:
2.Broke.Girls.S04E0X.Y.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP
anstatt X und Y nehmen wir nun einmal ~ für eine Variable Zahl und # für einen Variablen String:
2.Broke.Girls.S04E0~.#.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP

Dann könnte man folgenden Regex benutzen:
^(.*?)\.([A-Za-z0-9]+~)\.#\.(.*?)$
Ergebnis wäre:
1. [0-13] `2.Broke.Girls`
2. [14-20] `S04E0~`
3. [21-22] `#`
4. [23-59] `GERMAN.DL.DUBBED.720p.WebHD.x264-TVP`

1 = [HS]
2 = [HIS]
3 =
4 = [D]
 
Ich hab ihn schon ganz gelesen. Hab ihn nur nicht ganz verstanden. So wie ich das jetzt verstehe versuchst du die "konstanten" Teile zu ermitteln indem du alle Element der Liste miteinander vergleichst. Richtig? Ist also der letzte Teil (das GERMAN.DUBBED etc) in der jeweiligen Liste IMMER gleich? Nur in anderen Listen könnte da was anderes stehen z.B. GERMAN.WASAUCHIMMER.DUBBED. Dann aber auch in der Liste immer gleich.

Komme ich der Sache näher?
 
Ich hab ihn schon ganz gelesen. Hab ihn nur nicht ganz verstanden. So wie ich das jetzt verstehe versuchst du die "konstanten" Teile zu ermitteln indem du alle Element der Liste miteinander vergleichst. Richtig? Ist also der letzte Teil (das GERMAN.DUBBED etc) in der jeweiligen Liste IMMER gleich? Nur in anderen Listen könnte da was anderes stehen z.B. GERMAN.WASAUCHIMMER.DUBBED. Dann aber auch in der Liste immer gleich.

Komme ich der Sache näher?

Du kommst der Sache näher ;-)

Ja, der Benutzer hat immer eine Liste von Serien gleichen Typs. Wenn da also statische Sachen am Ende sind, die nicht identisch sind, dann wird das natürlich schief gehen, aber dafür gibt es dann eine Vorschaufunktion, was aber nicht teil dieses Threads ist.

Input list:
South.Park.S18E01.Leckt.euch.selbst.GERMAN.DL.DUBBED.1080p.WebHD.x264-TVP
South.Park.S18E02.Glutenfreies.Ebola.GERMAN.DL.DUBBED.1080p.WebHD.x264-TVP
South.Park.S18E03.Die.Cissy.GERMAN.DL.DUBBED.1080p.WebHD.x264-TVP
South.Park.S18E04.Handicar.GERMAN.DL.DUBBED.1080p.WebHD.x264-TVP

Output Pattern:
South.Park.S18E0*.*.GERMAN.DL.DUBBED.1080p.WebHD.x264-TVP

Input list:
The.Originals.S02E01.Die.Wiedergeburt.GERMAN.DUBBED.DL.1080p.WebHD.x264-TVP
The.Originals.S02E02.Gesund.und.Munter.GERMAN.DUBBED.DL.1080p.WebHD.x264-TVP
The.Originals.S02E03.Familienangelegenheiten.GERMAN.DUBBED.DL.1080p.WebHD.x264-TVP

Output Pattern:
The.Originals.S02E0*.*.GERMAN.DUBBED.DL.1080p.WebHD.x264-TVP


Jede Liste für sich.


[HS].[HIS]..[D] trifft zwar hier auf alle zu, und dabei wird es wohl auch erstmal bleiben, weil texte zerlegen sehr komplex ist.
 
Dann würde ich vorschlagen zunächst ein Methode zu schreiben, die den gemeinsamen Zustatz zum Titel herausfindet (anhand der gesamten Liste). Und dann einfach mit einem gewöhnlichen RegEx den Rest erledigen. Also in etwa so:

Java:
String[] liste = {
		"2.Broke.Girls.S04E01.Das.Reality.Problem.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP",
		"2.Broke.Girls.S04E02.Der.Bio.Club.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP",
		"2.Broke.Girls.S04E03.Von.Fischen.und.Baeren.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP",
		"2.Broke.Girls.S04E04.Das.verstrickte.Fahrrad.GERMAN.DL.DUBBED.720p.WebHD.x264-TVP"
};

String constant = findCommonGround(liste);

for(String s : liste)
{
	Pattern p = Pattern.compile("\\.[Ss][0-9]{1,3}[Ee][0-9]{1,3}\\.");
	Matcher m = p.matcher(s);
	
	if(m.find())
	{
		String show = s.substring(0, m.start());
		String rest = s.substring(m.end(), s.length());
		String title = rest.substring(0, rest.indexOf(constant));
		String group = m.group();
		String seasonEpisode = group.substring(1, group.length() - 1);
		
		System.out.println(show + " - " + seasonEpisode + " - " + title);
	}
}

Das Ergebnis von findCommonGround wäre hier: ".GERMAN.DL.DUBBED.720p.WebHD.x264-TVP".
 
Zuletzt bearbeitet:

Zurück
Oben