RegEx, wieder einmal ... :-(

Status
Nicht offen für weitere Antworten.
T

tuxedo

Gast
Hallo,

ich habe folgenden String:

Code:
param1=value1;param2=Hallo\;Welt;param3=value3

Diesen will ich mit
Code:
split()
aufsplitten, so dass ich nachher einzelne key-value Paare habe.

Getrennt sind die einzelnen key-value Paare wie man sehen kann mit
Code:
;
. Der key ist vom value mit
Code:
=
getrennt. Ergänzend kommt hinzu dass ein Value durchaus ein
Code:
;
beinhalten darf. Dieses muss also mit einem
Code:
\
escaped werden.

Mein Problem ist nun:

Ich muss den String an den Stellen splitten, an denen ein
Code:
;
vorkommt, aber nicht wo
Code:
\;
steht.

In Pseudo-Regex wäre das dann:
Code:
NICHT(\);

In der ApiDoc hab ich als einziges "NICHT" das "^" Symbol in verbindung mit Character-Classes "[....]" gefunden.

Also hab ich's so probier:

Java:
[^\\];

Aber da krieg ich

Java:
Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed character class near index 4
[^\];
    ^

Habs dann mit

Java:
[^\\\\];

probiert, das compiliert, aber gibt seltsame Ergebnisse ...
Kann mir jemand auf die Sprünge helfen?

- Alex
 
S

SlaterB

Gast
seltsame Ergebnisse.., klasse Fehlerbeschreibung,

na dann eben eine seltsame Antwort:
Java:
public class Test
{
    static String st = "param2=Hallo\\;Welt;param3=value3";

    public static void main(String[] args)
    {
        find(";.{4}");
        find("t;.{4}");
        find("[^\\\\];.{4}");

    }

    static void find(String pattern)
    {
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(st);
        if (m.find())
        {
            System.out.println(m.group());
        }
    }
}
 
T

tuxedo

Gast
Naja, soo einseitig kann man meinen Post ja nicht interpretieren. Ich hab ne Exception und das verursachende RegEx angegeben, sowie ein weiteres regex das die anforderung die ich beschrieben hatte nicht erfüllt.

Aber gut, ich hab mit dein Sample mal angeschaut:

Java:
;.{4}

Okay, das leuchtet mir ein, passt aber nicht. Er würde das ; nehmen und dann 4 weitere Zeichen beliebiger Art.

Java:
t;.{4}

gleiches wie beim ersten, nur dass das ganze mit einem t beginnt.

Java:
[^\\\\];.{4}

Da kommt das gleiche raus wie beim letzten?!

Vielleicht hab ich meine Anforderung an den String nicht genau genug definiert. Also nochmal im Detail:

1) Ich hab Key-Value Paare. Die String-Länge des Key und des Values sind nicht festgelegt und können somit von Paar zu Paar variieren.
2) Key und Value sind mittels
Code:
=
voneinander getrennt
2) Die Paare selbst sind mittels
Code:
;
voneinander getrennt
3) Der Value-String kann ebenfalls
Code:
;
und
Code:
=
enthalten, welche dann aber mit
Code:
\
escaped werden müssen, so dass im Value-String dann ein oder mehrere
Code:
\;
oder auch
Code:
\=
vorkommen können.


Hier mal ein Beispielcode:

Java:
public class Test
{
 
    public static void main(String[] args)
    {
        String st = "p1=va\\=l1;para2=Hallo\\;Welt;parameter3=value3";
        
        String[] pairs = st.split("[^\\\\];"); // splitte in Paare
        
        for (String pair : pairs)
        {
            System.out.println("Pair.: "+pair);
            
            String[] keyValue = pair.split("[^\\\\]="); // splitte in Key-Value
            
            System.out.println("Key..: "+keyValue[0]);
            System.out.println("Value: "+keyValue[1]);
            System.out.println();
        }
    }
}

Gewünschter Output:
Code:
Pair.: p1=va\=l1
Key..: p1
Value: va\=l1

Pair.: para2=Hallo\;Welt
Key..: para2
Value: Hallo\;Welt

Pair.: parameter3=value3
Key..: parameter3
Value: value3

Stattdessen bekomme ich aber mit obigen RegEx Werten folgendes:

Code:
Pair.: p1=va\=l
Key..: p
Value: va\=l

Pair.: para2=Hallo\;Wel
Key..: para
Value: Hallo\;Wel

Pair.: parameter3=value3
Key..: parameter
Value: value3

Wie man sieht gehen hier und da Zeichen verloren. Die Frage ist jetzt: Wie müssen die RegEx Werte aussehen damit das gewünschte Ergebnis rauskommt?

Das Rückgängig machen der Escape-Sequenzen (
Code:
\=
->
Code:
=
und
Code:
\;
->
Code:
;
) krieg ich hin. Nur das entsprechende splitten und die dafür nötige RegEx nicht :-(

- Alex
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
Naja, soo einseitig kann man meinen Post ja nicht interpretieren. Ich hab ne Exception und das verursachende RegEx angegeben,
war kein wirklich offener Teil der Frage ;)
sowie ein weiteres regex das die anforderung die ich beschrieben hatte nicht erfüllt.
aber warum? mein Beispiel hat gezeigt, das es geht, wobei 'das' eben nicht besonders genau beschrieben war

Aber gut, ich hab mit dein Sample mal angeschaut:

Java:
;.{4}

Okay, das leuchtet mir ein, passt aber nicht. Er würde das ; nehmen und dann 4 weitere Zeichen beliebiger Art.
Ziel war hier, dass das erste, falsche ; ausgewählt wird, die 4 Zeichen um das zu erkennen
Java:
t;.{4}

gleiches wie beim ersten, nur dass das ganze mit einem t beginnt.
hier nun das zweite richtige ;, durch die recht unfaire Vorgabe des genau passenden Buchstabens

Java:
[^\\\\];.{4}

Da kommt das gleiche raus wie beim letzten?!
genau, hier nun aber mit dem allgemein-richtigen Pattern ^\\\\, welches du angezweifelt hattest,
-> also funktioniert es, das war die Aussage meines Programms

kann natürlich sein, dass du ein bestimmte Problemstellung meinst, wo das nicht dann nicht anwendbar ist


Vielleicht hab ich meine Anforderung an den String nicht genau genug definiert. Also nochmal im Detail:
[..]
die schicke split-Methode kann man mit [^\\\\]; schlecht benutzen, da sonst das Zeichen vor dem ; verschluckt wird

neues Programm:
Java:
public class Test
{
    static String st = "p1=va\\=l1;para2=Hallo\\;Welt;parameter3=value3";

    public static void main(String[] args)
    {
        find("[^\\\\];");
    }

    static void find(String pattern)
    {
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(st);
        while (m.find())
        {
            System.out.println(m.start());
        }
    }
}
liefert 8 + 28, mit diesen beiden Infos kann mit subString usw. zum Ziel kommen,
evtl. noch Spezialfälle beachten, z.B. ; am Anfang als erstes Zeichen


-----

vielleicht kann man alternativ zu subString auch irgendwas mit den Matcher-Methoden basteln,
die Original-split-Methode, die auch String.split() benutzt, ist
Java:
public String[] split(CharSequence input, int limit) {
        int index = 0;
        boolean matchLimited = limit > 0;
        ArrayList<String> matchList = new ArrayList<String>();
        Matcher m = matcher(input);

        // Add segments before each match found
        while(m.find()) {
            if (!matchLimited || matchList.size() < limit - 1) {
                String match = input.subSequence(index, m.start()).toString();
                matchList.add(match);
                index = m.end();
            } else if (matchList.size() == limit - 1) { // last one
                String match = input.subSequence(index,
                                                 input.length()).toString();
                matchList.add(match);
                index = m.end();
            }
        }

        // If no match was found, return this
        if (index == 0)
            return new String[] {input.toString()};

        // Add remaining segment
        if (!matchLimited || matchList.size() < limit)
            matchList.add(input.subSequence(index, input.length()).toString());

        // Construct result
        int resultSize = matchList.size();
        if (limit == 0)
            while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
                resultSize--;
        String[] result = new String[resultSize];
        return matchList.subList(0, resultSize).toArray(result);
    }
 

faetzminator

Gesperrter Benutzer
Grundsätzlich findest du es mit der Regex [c]"[^\\\\];"[/c] oder - falls \ mit \\ escaped werden muss - schöner [c]"[^\\\\](\\\\{2})*;"[/c]. Das Problem dabei ist, dass er dann bis zum letzten nicht-\ abschneidet.
 
T

tuxedo

Gast
die schicke split-Methode kann man mit [^\\\\]; schlecht benutzen, da sonst das Zeichen vor dem ; verschluckt wird

Gibts hierfür eine Erklärung? Das mit dem verschlucken hab ich ja bereits selbst rausgefunden :-( Aber so richtig einleuchten will's mir nicht warum das Zeichen hopps gehen...

- Alex
 

faetzminator

Gesperrter Benutzer
wenn du foo-bar-baz auf - splittest, erhälst du auch foo, bar und baz. Die gematchten Zeichen werden bei split() einfach geschluckt.
 
V

Vayu

Gast
wieso formatierst du den string mit key/value nicht wie bei csv dateien?

"key=value";"key2=cval;bl";"key3=halld="

dann musst du auch nicht escapen ...
 
T

tuxedo

Gast
wenn du foo-bar-baz auf - splittest, erhälst du auch foo, bar und baz. Die gematchten Zeichen werden bei split() einfach geschluckt.

Das leuchtet mir ein. Aber bei mir werden ja Zeichen geschluckt die nicht auf die RegEx matchen:

Code:
Pair.: p1=va\=l
Key..: p
Value: va\=l


@Vayu

Ja leider kann ich mir den String nicht aussuchen. Der ist schon so. Ich muss ihn nur parsen.


- Alex
 
S

SlaterB

Gast
> Aber bei mir werden ja Zeichen geschluckt die nicht auf die RegEx matchen:
?
das Pattern ist
[^\\\\]=

'irgendein Zeichen, nicht \' sowie '='

also wird "p1=va\=1" angeschaut, 'irgendein Zeichen, nicht \' ist Zeichen 2, die 1, '=' ist Zeichen 3,
Zeichen 2 und 3 fliegen raus, die sind ja die Split-Zeichen,

was übrig bleibt, siehst du ja
 
T

tuxedo

Gast
Ah, okay, jetzt leuchtet's ein ... Okay, dann werde ich ne eigene split() Methode basteln müssen. Danke mal soweit.

- Alex
 
V

Vayu

Gast
sollte auch ausreichend schnell sein, ohne regex etc ...

Java:
public static HashMap<String, String> parse(String text) {
        char[] c = text.toCharArray();
        boolean key = true;
        HashMap<String, String> ret = new HashMap<String, String>();
        String tmpKey = "";
        String tmpVal = "";
        for(int i=0; i < c.length; i++) {
            if(c[i] == '=' && i != 0 && c[i-1] != '\\') {
                key = false;
                continue;
            }
            if(c[i] == ';' && i != 0 && c[i-1] != '\\') {
                ret.put(tmpKey, tmpVal);
                tmpVal = tmpKey = "";
                key = true;
                continue;
            }
            if(key)
                tmpKey += c[i];
            else
                tmpVal += c[i];
        }
        ret.put(tmpKey, tmpVal);
        return ret;
    }
 
V

Vayu

Gast
was ist an continue schlimm?

Ist übrigens super nur zu schreiben "gott bist du blöd" statt gleich noch zu sagen wieso ... DAS ist schlechter Stil bygones ...
 
Zuletzt bearbeitet von einem Moderator:
B

bygones

Gast
was ist an continue schlimm?

Ist übrigens super nur zu schreiben "gott bist du blöd" statt gleich noch zu sagen wieso ... DAS ist schlechter Stil bygones ...

hey war kein persoenlicher Angriff... nicht gleich den Knueppel rausholen, ich habe nicht mal ansatzweise das wort "bloed" geschrieben... fuer eigeninterpretationen bin ich nicht verantwortlich !

ich mag continue einfach nicht - umkehrung der condition und gut is
ich mag auch kein break - schreit nach auslagern in eine methode


ich muss aber auch ehrlich sagen ich versteh deine methode nicht wirklich... trifft das eine oder andere zu wird irgendwas gesetzt und dann weitergegangen... wenn keins trifft wird der zustand von key genommen, der irgendwann mal gesetzt wurde und was gemacht.

ich finds einfach nicht gut zu lesen bzw zu verstehen.

hoffe das hat nun deine sensibilitaet nicht zu sehr gestresst
 
V

Vayu

Gast
überleg dir einfach wie du drauf reagiert hättest, hätte ich unter einen post von dir so etwas geantwortet ... ich kann mit kritik umgehen, wenn sie sachlich rüberkommt ...

und was tue ich in der methode?

erste if -> schau ob ein = gefunden wurde, welches nicht escaped ist, dann ist der key im string am ende
wird ein ; gefunden, welches nicht escaped ist, ist auch der value am ende angelangt und ich kann beide in die hashmap übertragen (key -> value)

der boolean wird einfach gesetzt, damit ich weiss an welchen string ich den eben gecheckten char anhänge.

wieso ich keinen regex benutze? Weil regex in Java um den faktor 10 langsamer ist, als einen string in ner for-schleife durchzulaufen.
 

Illuvatar

Top Contributor
Was hältst du von einem Lookbehind?
[Java]public class Test
{

public static void main(String[] args)
{
String st = "p1=va\\=l1;para2=Hallo\\;Welt;parameter3=value3";

String[] pairs = st.split("(?<!\\\\);"); // splitte in Paare

for (String pair : pairs)
{
System.out.println("Pair.: "+pair);

String[] keyValue = pair.split("(?<!\\\\)="); // splitte in Key-Value

System.out.println("Key..: "+keyValue[0]);
System.out.println("Value: "+keyValue[1]);
System.out.println();
}
}
}[/Java]
 
B

bygones

Gast
überleg dir einfach wie du drauf reagiert hättest, hätte ich unter einen post von dir so etwas geantwortet ... ich kann mit kritik umgehen, wenn sie sachlich rüberkommt ...
ich haette einfach deinen ersten satz geschrieben... die interpretation danach war fehl am platze...

bygones - themenfremd
 
V

Vayu

Gast
cool, so geht das! Danke Illuvatar!

@bygones
das würde ich jetzt auch sagen ;)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Regex... mal wieder Allgemeine Java-Themen 3
GilbertGrape mal wieder ne Regex-Frage Allgemeine Java-Themen 2
G Schon wieder Regex Problem :-/ Allgemeine Java-Themen 6
M statische regex und vergleiche oder immer wieder compilen Allgemeine Java-Themen 2
U schon wieder regex Allgemeine Java-Themen 3
H Frage regex greater than less than Allgemeine Java-Themen 7
N Regex schlägt nicht an Allgemeine Java-Themen 10
W Variable Initialisierung mit dem Ergebnis einer Regex Allgemeine Java-Themen 1
T regex case insensitive trimmed Allgemeine Java-Themen 6
S Zeichen | in regex Allgemeine Java-Themen 8
X Regex mit mehreren Bedingungen machen Allgemeine Java-Themen 5
N Hilfe bei RegEx benötigt Allgemeine Java-Themen 3
C Java17 und Regex Allgemeine Java-Themen 13
OnDemand RegEx /compilebekomme nicht die erwarteten Werte Allgemeine Java-Themen 9
N Gierigen Regex in nicht-gierigen umwandeln Allgemeine Java-Themen 4
N E-Mail Validator (ohne Regex!) Allgemeine Java-Themen 7
OnDemand Regex von bis Allgemeine Java-Themen 6
W Versionsnummer auslesen - Regex ist zickig Allgemeine Java-Themen 2
L RegEx für Teile einer Berechnung Allgemeine Java-Themen 14
G Regex Allgemeine Java-Themen 2
L regex ganzer string? Allgemeine Java-Themen 2
MiMa Geldbetrag mit regex ermitteln. Allgemeine Java-Themen 14
W RegEx Stringliteral finden - Jflex Allgemeine Java-Themen 5
D Regex Probleme Allgemeine Java-Themen 2
Kirby.exe Regex charakter ignorieren Allgemeine Java-Themen 12
S Java SAT (Haltbarkeitsproblem) mit Regex Allgemeine Java-Themen 6
S [Regex] Nur diese Zeichen beachten Allgemeine Java-Themen 1
M Bitte Hilfe mit REGEX (Negieren) Allgemeine Java-Themen 4
J Compilerfehler bis in java.util.regex.Pattern... Allgemeine Java-Themen 2
C PDFBox: Nach RegEx ganze Zeile Allgemeine Java-Themen 4
S Regex mit UND-Verknüpfung Allgemeine Java-Themen 1
P RegEx für Zeiten Allgemeine Java-Themen 7
D Regex: Komplettes Wort bekommen Allgemeine Java-Themen 3
Neumi5694 Operatoren regEx für das Erstellen eines Strings verwenden Allgemeine Java-Themen 3
P RegEx Allgemeine Java-Themen 3
W String Parsen und auf eigenes Muster anwenden (kein Regex) Allgemeine Java-Themen 11
Y regex | n-faches Vorkommen oder gar keins Allgemeine Java-Themen 6
turmaline Regex gegen Regex prüfen Allgemeine Java-Themen 4
HarleyDavidson Regex - Optimierung Allgemeine Java-Themen 4
M Regex für Zahleneingabe in JavaFX Textfield Allgemeine Java-Themen 18
T Best Practice Wortregeln RegEx Allgemeine Java-Themen 11
A ALTER TABLE mit Hilfe von RegEx zerlegen, splitten Allgemeine Java-Themen 5
H Interpreter-Fehler Regex kompiliert nicht Allgemeine Java-Themen 5
M RegEx alle Matches ausgeben Allgemeine Java-Themen 5
Iron Monkey Mit Regex nach Beträge suchen Allgemeine Java-Themen 4
T REGEX Erklaerung Allgemeine Java-Themen 14
T Nur innerhalb des regex-Match ersetzen Allgemeine Java-Themen 9
H Pic Download / Regex Problem Allgemeine Java-Themen 7
F Frage zu Regex möglich Allgemeine Java-Themen 4
H RegEx - Ersetze alles bis Leerzeichen Allgemeine Java-Themen 5
S regex verbrät CPU Allgemeine Java-Themen 6
V Regex Bereichs Filter Allgemeine Java-Themen 4
127.0.0.1 RegEx _ und 0-9 Allgemeine Java-Themen 45
S Entfernen von allen Nicht-Buchstaben chars aus einem String ohne Regex..? Allgemeine Java-Themen 10
P Java String Regex Allgemeine Java-Themen 2
AyKay Regex XPath Allgemeine Java-Themen 4
C Regex (Case insensitive und Umlaute) Allgemeine Java-Themen 4
D Regex Raute erkennen Allgemeine Java-Themen 2
nrg Zweistelligen Zahlenbereich mit RegEx Allgemeine Java-Themen 8
GilbertGrape Regex-Problem Allgemeine Java-Themen 2
W Denkblockade RegEx Allgemeine Java-Themen 2
S eigene regEx schreiben Allgemeine Java-Themen 4
C Regex expandieren Allgemeine Java-Themen 6
C Regex Überschniedung von Ausdrücken Allgemeine Java-Themen 16
reibi RegEX - Teilstring Allgemeine Java-Themen 6
R Java-RegEx terminiert nicht Allgemeine Java-Themen 3
M Regex: Ich stehe auf dem Schlauch Allgemeine Java-Themen 2
V Kleines Regex-Problem Allgemeine Java-Themen 3
B Regex "Problem" Allgemeine Java-Themen 4
B RegEx: (Um-)formulieren eines Pattern zur Identifizierung komplexer URLs Allgemeine Java-Themen 7
P RegEx mit HTML Parser für Java möglich? Allgemeine Java-Themen 10
J Regex: Fertige URLS aus Javascript Allgemeine Java-Themen 3
N Java regex Allgemeine Java-Themen 5
K Regex JSON Allgemeine Java-Themen 3
J RegEx Ausdruck Allgemeine Java-Themen 2
J Regex: URLS aus CSS Allgemeine Java-Themen 2
G RegEx- Ausdruck Allgemeine Java-Themen 4
G RegEx kein Unterstrich Allgemeine Java-Themen 2
A Text via RegEx durchsuchen und teile ersetzten Allgemeine Java-Themen 5
C Regex: Zahl ohne führende Null Allgemeine Java-Themen 13
W RegEx Zeile parsen Medium Allgemeine Java-Themen 8
X Java String Regex - Sonderzeichen Filtern Allgemeine Java-Themen 5
S Dateiname mit Regex parsen Allgemeine Java-Themen 3
Loyd Noch ne Regex-Frage: Verschachtelte Ausdrücke Allgemeine Java-Themen 4
R Java Regex Frage Allgemeine Java-Themen 17
Daniel_L RegEx-Frage: Ersetzen in UBB ausschließen Allgemeine Java-Themen 2
M Große Datei mit Regex durchsuchen Allgemeine Java-Themen 4
S regex für einen Link Allgemeine Java-Themen 3
E Regex alles nach ? löschen Allgemeine Java-Themen 4
M RegEx-Frage Allgemeine Java-Themen 2
R Regex Tokenizer Allgemeine Java-Themen 11
E Regex HTML Tag und Inhalt löschen Allgemeine Java-Themen 4
H RegEX und eMail Allgemeine Java-Themen 4
L-ectron-X Regex zum Entfernen von mehrzeiligen Kommentaren Allgemeine Java-Themen 2
martin82 Regex - JTable - Filter Allgemeine Java-Themen 10
nrg Kleine Hilfe mit RegEx Allgemeine Java-Themen 2
B Regex-Fehler nach lib-Update Allgemeine Java-Themen 2
K Contrains oder Regex Allgemeine Java-Themen 3
J replaceAll , "[", "]" & regex Allgemeine Java-Themen 12
P RegEx und $-Zeichen als Literal Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben