tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
7
ZUGRIFFE
283
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    911
    Hallo und Halli,
    ich habe auf grund eines Phänomens ein Testprogramm gebaut, welches ein bischen replaceAll tut.
    Ziel ist es die Namespace-angaben aus sowohl den Start als auch den EndeTags im XML-Teilstring zu entfernen.

    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    public class ReplaceAllTest
    {
        
        static private void multiReplaceAll(String inputString, String regex[], String replacement[])
        {
            for (int i=0; i<regex.length; i++)
            {
                System.out.println(inputString);
                inputString = inputString.replaceAll(regex[i], replacement[i]);
                
            }
            System.out.println(inputString);
            System.out.println("----");
        }
        
        static public void main (String[] args)
        {
            //String inputString = "<bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id>";
            String inputString = "<ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr></bb3.1.2:PrvtId></bb3.1.2:Id></ar:CdtrSchmeId>";
            String[] regex       = new String[] {"</.*?:","<.*?:"};
            String[] replacement = new String[] {"</","<"};;
            
            multiReplaceAll(inputString, regex, replacement);
            
            inputString = "<bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr>";
            multiReplaceAll(inputString, regex, replacement);
            
            inputString = "<bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id>";
            multiReplaceAll(inputString, regex, replacement);
        }
    }

    hier die Ausgabe:
    <ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr></bb3.1.2:PrvtId></bb3.1.2:Id></ar:CdtrSchmeId>
    <ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</Prtry></SchmeNm></Othr></PrvtId></Id></CdtrSchmeId>
    <CdtrSchmeId><Id><PrvtIdZ><Othr><Id>DE09ZZZ00000000001<SchmeNm><Prtry>SEPA</Prtry></SchmeNm></Othr></PrvtId></Id></CdtrSchmeId>
    ----
    <bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr>
    <bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</Prtry></SchmeNm></Othr>
    <Othr><Id>DE09ZZZ00000000001<SchmeNm><Prtry>SEPA</Prtry></SchmeNm></Othr>
    ----
    <bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id>
    <bb3.1.2:Id>DE09ZZZ00000000001</Id>
    <Id>DE09ZZZ00000000001</Id>
    ----

    nur die letzte Ausgabe ist wie erwartet.
    bei den anderen beiden oben fehlt das Ende-Tag von <ID>

    Sieht aus meiner Sicht zunächst aus wie ein Bug!

    Wie kann man sich das erklären?
    Gäbe es dazu einen Workaround? Wer kennt eine bessere Regex-Formulierung, die mir das gewünschte ergebnis gibt?

    mit amkopfkratzenden Grüßen

    Takidoso
    Geändert von takidoso (15.09.11 um 14:10 Uhr) Grund: verbesserte Hervorhebung
     

  2. #2
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi,

    also ich kann mir das auch nicht so wirklich erklären. Aber bei deine Regex würde ich ein wenig ändern:
    Code java:
    1
    
    String[] regex       = new String[] {"</.*:","<.*:"};
    Wenn die Fragezeichen (Zeichen kommt ein- oder keinmal vor) weg sind, dann kann es nur matchen, solange der String den Teil enthält den du entfernen willst. Denke ich zumindest. Habe es selber nicht ausprobiert.

    // ---
    // EDIT
    Jetzt fällt mir auch gerade noch auf, dass beide Regexe gleich matchen.
    Ob du das nun so schreibst '</.*:' oder so '<.*:' ist vollkommen egal, da '.*' auf alle Zeichen (einschließlich '/') matchen sollte.

    Gruß

    Fabio
    Geändert von Fabio Hellmann (15.09.11 um 14:23 Uhr)
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  3. #3
    CPoly CPoly ist offline Mitglied Weizenbier
    tutorials.de Premium-User
    Registriert seit
    Sep 2009
    Beiträge
    2.445
    Hier mal meine Vorschlag für einen Ausdruck:

    Code java:
    1
    
    System.out.println( inputString.replaceAll("<(\\/?)(?>.+?):(.+?)>", "<$1$3>") );
    Geändert von CPoly (15.09.11 um 14:44 Uhr)
     

  4. #4
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    911
    Nun weiß ich warum es nicht funktioniert.
    Nebenbei das *? in meinen Ausdrücken ist als Quantifier gedacht der da aussagt "reluctant" zu sein

    Hier eine tabelle diesbezüglich:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    Greedy   Reluctant  Possessive Meaning 
    --------------------------------------------------------------------
    X?        X****       X?+      X, once or not at all 
    X*        X*?         X*+      X, zero or more times 
    X+        X+?         X++      X, one or more times 
    X{n}     X{n}?       X{n}+     X, exactly n times 
    X{n,}    X{n,}?      X{n,}+    X, at least n times 
    X{n,m}   X{n,m}?   X{n,m}+     X, at least n but not more than m times

    Nun zur Erläuterung was er bei den Fehlsituationen tatsächlich (richtig) gemacht hatte (also kein Bug)

    <bb3.1.2:Id>DE09ZZZ00000000001</Id><bb3.1.2:SchmeNm>...
    er sieht und änder tdie erste Stelle wo er den Ausdruck findet
    und hier ist die 2. Stelle die er findet:
    <bb3.1.2:Id>DE09ZZZ00000000001</Id><bb3.1.2:SchmeNm>

    um das zu beheben ist die 2. ReGex zu korrigieren, in dem man sagt das man einen String sucht der keine spitze-Klammer-auf enthält
    also anstelle von:
    Code :
    1
    
    "<.*?:"
    dieses hier
    Code :
    1
    
    "<[^<]*?:"

    und dann klappt es auch (mit dem Nachbarn )

    in diesem Sinne

    Takidoso
     

  5. #5
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    911
    Zitat Zitat von CPoly Beitrag anzeigen
    Hier mal meine Vorschlag für einen Ausdruck:

    Code java:
    1
    
    System.out.println( inputString.replaceAll("<(\\/?)(?>.+?):(.+?)>", "<$1$3>") );
    das habe ich nun auch mal ausprobiert:

    Code java:
    1
    2
    
    inputString = "<ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr></bb3.1.2:PrvtId></bb3.1.2:Id></ar:CdtrSchmeId>";
    System.out.println( inputString.replaceAll("<(\\/?)(?>.+?):(.+?)>", "<$1$3>") );

    hier der output:
    Code :
    1
    
    <ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr></bb3.1.2:PrvtId></bb3.1.2:Id></ar:CdtrSchmeId>

    drollig es scheint hier alls unverändert
    aber danke trotzdem
     

  6. #6
    CPoly CPoly ist offline Mitglied Weizenbier
    tutorials.de Premium-User
    Registriert seit
    Sep 2009
    Beiträge
    2.445
    Ich hatte den Beitrag editiert, um aus der mittleren Gruppe eine atomare Gruppe zu machen, weil wir für die zweite Gruppe keine Rückwärtzreferenz benötigen. Hätte es aber vorher testen sollen (bzw. habe es nicht kompiliert, sondern nur ausgeführt)

    Code java:
    1
    
    System.out.println( inputString.replaceAll("<(\\/?)(.+?):(.+?)>", "<$1$3>") );
     

  7. #7
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    911
    wo hast du es denn ausgeführt, wenn Du es nicht kompliiert hast****?
    Aber Du hattest mich durchaus auf eine andere ähnliche Idee gebracht um nicht zweimal einen Replace machen zu müssen:
    Code java:
    1
    2
    
    inputString = "<ar:CdtrSchmeId><bb3.1.2:Id><bb3.1.2:PrvtIdZ><bb3.1.2:Othr><bb3.1.2:Id>DE09ZZZ00000000001</bb3.1.2:Id><bb3.1.2:SchmeNm><bb3.1.2:Prtry>SEPA</bb3.1.2:Prtry></bb3.1.2:SchmeNm></bb3.1.2:Othr></bb3.1.2:PrvtId></bb3.1.2:Id></ar:CdtrSchmeId>";
    System.out.println( inputString.replaceAll("(<|</)[^/]+?:(.+?>)", "$1$2") );
    Ich wußte gar nicht dass bei dem Replace auch die Gruppen die man findet ersetzt werden können insofern wieder was neues gelernt :-D
     

  8. #8
    CPoly CPoly ist offline Mitglied Weizenbier
    tutorials.de Premium-User
    Registriert seit
    Sep 2009
    Beiträge
    2.445
    Du kannst sogar in dem Suchstring die Gruppen direkt nochmal verwenden. Das ist zum Beispiel praktisch, wenn du öffnende und die dazu gehörigen schließenden Tags suchst.

    Ich habe in der Konsole nur Pfeil hoch + Enter gedrückt ("java Program") anstatt zweimal hoch ("javac Program.java"). Wenn man sonst nur mit Skript sprachen zu tun hat, vergisst man das kompilieren manchmal und für so was starte ich keine IDE.
     

Ähnliche Themen

  1. String.replaceAll regex
    Von crashfinger im Forum Java
    Antworten: 2
    Letzter Beitrag: 06.01.11, 15:42
  2. Antworten: 5
    Letzter Beitrag: 22.11.10, 17:31
  3. Verständnisproblem mit String.replaceAll
    Von takidoso im Forum Java
    Antworten: 3
    Letzter Beitrag: 30.04.07, 18:22
  4. String replaceAll() Problem
    Von wSam im Forum Java
    Antworten: 6
    Letzter Beitrag: 27.02.07, 19:06
  5. String replaceAll
    Von js-mueller im Forum Java
    Antworten: 7
    Letzter Beitrag: 31.01.06, 19:04