Split() Methode funktioniert nicht?!

Hey,
ich habe einen sehr langen String, der HTML-Code repräsentiert. In diesem möchte ich nun String.split() ausführen.

Es funktioniert aber nicht! Der resultierende Array hat immer genau die Länge 1.

Ich habe geprüft, ob er denn wenigstens erkennt, dass das regex im String enthalten ist und contains liefert true. Und es ist nicht am Ende enthalten.

Daher, wieso hat wird der String nicht gespalten?! Wieso hat der Array nur genau 1 Element...

Ich verstehe das nicht.

Liegt es vlt. an der Länge des Strings? Gibt es Alternativen? Wie ist das Problem zu lösen?

Vielen vielen Dank!
Tabkas
 
Daher, wieso hat wird der String nicht gespalten?! Wieso hat der Array nur genau 1 Element...
Mit an Sicherheit grenzender Wahrscheinlichkeit, weil Du etwas falsch gemacht hast. Man könnte jetzt die Vermutung anstellen, dass es mit der Angabe des regulären Ausdrucks zu tun hat, aber wir wollen es mal nicht übertreiben :)
 
Hier die Methode. Es geht darum die Zeichen zwischen zwei bestimmten Zeichen zu ersetzen:

public static String ersetzeMitte(String text, String einsetzen, String anfang, String ende) {
if(!text.contains(anfang) || !text.contains(ende)) {return text;}
String rueck = "";

String[] liste = text.split(anfang);
rueck += liste[0];

rueck += einsetzen;

String zweiterTeil = liste[1];
rueck += zweiterTeil.split(ende)[1];

return rueck;
}

Es ist unsauber programmiert, ja. ZB hätte vor zweiterTeil.split(ende)[1] noch eine Abfrage gemusst, ob dieses Element überhaupt existiert. Analog bei liste[1]. Ich habe darauf verzichtet, da dies in meiner Anwendung mit Sicherheit nicht vorkommt, und wenn, behandle ich es als Ausnahme.

Die Eingabe der Aktualparameter erfolgt auch in der richtigen Reihenfolge, mehrmals geprüft.

text ist ein sehr langer HTML-Code
einsetzen ist ein kurzer neuer Produkttitel
anfang ist dabei: "<!--[PRODUKTTITEL-START]-->"
ende ist dabei: "<!--[PRODUKTTITEL-ENDE]-->"

Fehlercode:
java.lang.ArrayIndexOutOfBoundsException: 1
at zeichenkette.Bearbeiten.ersetzeMitte(Bearbeiten.java:37)

Das heißt der String wird nicht in 2 Teile gespalten bei "<!--[PRODUKTTITEL-START]-->". Obwohl das im String vorkommt und auch nicht erst am Ende, sondern mittendrin.

Wieso?

Vielen Dank!
 
Das Problem wird wohl sein, dass deine beiden Suchstrings vordefinierte Zeichen in regulären Ausdrücken enthalten. (zum Beispiel []... gleiches gilt für Bindestrich und spitze Klammern <>)
Versuch sowohl anfang als auch ende mal mit Pattern.quote(String) zu escapen. Dabei werden alle vordefinierten Zeichen als "normale" Zeichen interpretiert.
 
Achso! Ich verstehe, ich werde dies heute Abend probieren, sobald möglich.

Ich verstehe richtig, dass Pattern.quote(...), was "\Q" und "\E" hinzufügt, nichts anderes tut, als dafür zu sorgen, dass der String, der übergeben wurde so gelesen wird, wie er geschrieben ist und nicht bestimmte Teile als vordefinierte Zeichen interpretiert werden?

Dankeschön!
 
K

kneitzel

Generell könnte man auch auf Split verzichten und einfache indexOf Aufrufe nutzen um dann im Anschluss substring zu nutzen.

Oder da es ja um das Ersetzen einer Zeichenkette geht natürlich ein replaceAll bzw replaceFirst Aufruf wobei dann das gesuchte Pattern halt Pattern.quote(anfang) + “.*“ + Pattern.quote(ende) wäre ... statt dem .* evtl. eingrenzen, was alles drin vorkommen darf, aber wenn es genau ein mal vorkommen kann ist .* ok.
 
Generell könnte man auch auf Split verzichten und einfache indexOf Aufrufe nutzen um dann im Anschluss substring zu nutzen.
Java:
    public static String replaceAllBetween(String text, String begin, String end, String replacement) {
        int pos = 0;
        int left;
        StringBuilder b = new StringBuilder();
        while ((left = text.indexOf(begin, pos)) != -1) {
            left += begin.length();
            b.append(text.substring(pos, left));
            pos = left;

            int right = text.indexOf(end, left);            
            if (right != -1) {
                b.append(replacement);
                pos = right;
            }
        }
        b.append(text.substring(pos));
        return b.toString();
    }
 
K

kneitzel

Danke, aber wie am Ende gesagt: String hat eine replace Funktion, die man dann ja nutzen kann:
Java:
  public static String replaceAllBetween(String text, String begin, String end, String replacement) {
    return text.replaceAll(
                   Pattern.quote(begin) + ".*?" + Pattern.quote(end),
                   begin+replacement+end
           );
  }
Ich war mir jetzt nur nicht sicher, ob die Zeichenketten begin und end erhalten bleiben sollten. Von der Benennung her hörte es sich danach an, daher habe ich diese auch drin gelassen....

Das .* kann bei mehreren Vorkommen natürlich recht hart sein, da es ja "greedy" ist, d.h. so viel nimmt wie nur möglich. Bei mehreren Vorkommen würde es also vom ersten anfang bis zum letzten ende alle nehmen. Daher das .*?, so dass es eben dieses Verhalten nicht mehr zeigt.

Und dann einfach einmal ein Test:
Java:
import java.util.regex.Pattern;

public class Test {
  public static void main(String[] args) {
    System.out.println(replaceAllBetween(
        "Das steht davor<!--[PRODUKTTITEL-START]-->Innen Drin ist dies   <!--[PRODUKTTITEL-ENDE]-->Und danach kommt auch noch was ...<!--[PRODUKTTITEL-START]-->Zweites Innen Drin ist dies   <!--[PRODUKTTITEL-ENDE]-->Ganz am Ende",
        "<!--[PRODUKTTITEL-START]-->",
        "<!--[PRODUKTTITEL-ENDE]-->",
        "lalala"));
  }

  public static String replaceAllBetween(String text, String begin, String end, String replacement) {
    return text.replaceAll(
                   Pattern.quote(begin) + ".*?" + Pattern.quote(end),
                   begin+replacement+end
           );
  }
}
Code:
c:\Projects>javac Test.java

c:\Projects>java Test
Das steht davor<!--[PRODUKTTITEL-START]-->lalala<!--[PRODUKTTITEL-ENDE]-->Und da
nach kommt auch noch was ...<!--[PRODUKTTITEL-START]-->lalala<!--[PRODUKTTITEL-E
NDE]-->Ganz am Ende

c:\Projects>
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben