# Werte mit regulären Ausdrücken aus String extrahieren



## Dany23 (9. September 2009)

Hallo,

ich beisse mir gerade seit etwa zwei Stunden die Zähne an einem Problem aus und hoffe, dass mir hier jemand helfen kann. Hört sich eigentlich ganz einfach an:

Ich habe einen String der ein XML Element enthält, aus diesem String möchte ich nun die Attributwerte extrahieren und in einer Variablen speichern. Dachte daran, das mit regulären Ausdrücken zu machen, für jedes Attribut einen. Bekomme das aber leider nicht hin. Kann mir da jemand helfen? Vielleicht hat auch jemand eine Idee wie sie das Problem besser lösen lässt.
Hier ein Beispiel des Strings:

product="<product kodierung="A" nummer="100001" produktmerkmal="A" speicherdatum="2004-04-30" speicheruhrzeit="00:00:00"> </product>";

Ziel soll es nun sein z.B. für die Variable nummer den Wert "100001" 
extrahieren zu können.

Würde mich über Hilfe freuen.
Grüße
Dany


----------



## chmee (9. September 2009)

Würde es nicht schon reichen, wenn Du einfach nur nach *nummer="* und *" produktmerkmal="* suchst?
Also als Regex -glaube ich- so : */(?<=nummer=").*(?=" produktmerkmal)/*

Wobei ich mich frage, warum Du nicht die XML-Konventionen nutzt, um die Daten zu erhalten. Aber keine Sorge, hab schon zu Genüge Daten mit Regex geparsed, die mit anderen Techniken effizienter wären

mfg chmee


----------



## DosCoder (9. September 2009)

Hi,
da fallen mir 2 Möglichkeiten ein:
1) Du suchst dir im String mit Hilfe  von _indexOf()_ den Variablennamen, gehst in diesem Unterstring weiter bis zum 1. Gänsefüsschen und liest den Wert bis zum 2.Gänsefüsschen ein. Über den genauen Algorithmus kann man sich jetzt streiten, aber es gibt ja bekanntlich viele Wege.
2) Du schaust dir mal DOM und SAX an. Diese sind XML-Bibliotheken für Java, mit denen man die Elemente einfach filtern kann.

Bei weiteren Fragen: Frage einfach!
Ciao
DosCoder

[EDIT]Wieder mal zu langsam...


----------



## Dany23 (9. September 2009)

Hallo,

danke für die Antworten.

@chmee: mit dem regulären Ausdruck finde ich schon nummer=", aber ich möchte ja gerne den Wert in die Variablen speichern. Das bekomme ich nicht hin.

@DosCoder: Mit der ersten Möglichkeit bekomme ich es hin. War auch mein erster Ansatz aber ich fand es wahnsinnig umständlich und dachte mit den regulären Ausdrücken wäre es eleganter. Die Variante würde ich fertigstellen wenn ich es anders gar nicht mehr hinbekomme.
Bei der zweiten Variante bin ich mir nicht sicher ob ich nicht mit Kanonen auf Spatzen schiesse. Ich bekomme diesen Datensatz angeliefert in einem XML File und ein Attribut beinhaltet eben diesen Auszug als Wert.


----------



## chmee (9. September 2009)

Naja, ich hab den Regextester benutzt, gibt es etwa unter Java andere Konventionen?
http://www.regex-tester.de/regex.html

Als Zweites dachte ich mir, ich such Dir alle "xxx" raus mit */="[^"]*"/* . Das Ergebnis ist ein Array aller Werte, mit diesem Pattern aber noch mit =" und " am Ende. Da müsste man nur das Ergebnisstring beschneiden..

mfg chmee


----------



## DosCoder (9. September 2009)

Hi,
und wie öffnest du die XML-File? Liest du das Ganze als Textdatei ein? Wenn ja, würde ich sagen, dass sich der Umstieg auf SAX oder DOM lohnt. Wenn ich dich jetzt falsch verstanden habe, und es wirklich nur um dieses Element geht, dann würde ich es mit den String-Methoden machen. Den SAX oder DOM bedeuteten, dass du auch immer die Bibliotheken mit deinem Programm herumschleppen musst.
Ciao
DosCoder

[EDIT] Dat gibst ja nicht, schon wieder zu lahm....


----------



## Dany23 (9. September 2009)

Ich lese das File mit jaxb ein.
Versuche jetzt nochmal mit:

java.util.regex.Pattern  p = java.util.regex.Pattern.compile( "nummer=\".*\"" ); 
Matcher m = p.matcher( "nummer=\"12\"" );

Allerdings bekomme ich es nicht hin das ich den ganzen String in ein Array gelesen bekomme.


----------



## Dany23 (9. September 2009)

Also das funktioniert nun, wobei es nicht besonders toll ist:


```
Pattern  p =Pattern.compile( "(?<=nummer=\").*(?=\" produktmerkmal)/" ); 
Matcher m = p.matcher( "nummer=\"12\"" ); 
if (m.find()) 	
System.out.println("ausgabe: "+m.group().substring(8,m.group().length()-1));
```

@chmee kannst Du mir noch einen Hinweis geben wie ich das komplett in ein Array bekomme wie Du vorgeschlagen hast?


----------



## DosCoder (9. September 2009)

Hi,
was meinst du, mit "den ganzen String in ein Array gelesen bekomme"?
Außerdem ist in Wikipedia zu lesen, dass JAXP DOM und SAX beinhaltet. Und mit diesen beiden Bibliotheken kann man bequem Attribute auslesen:

```
String value = new SAXBuilder().build(new InputSource("main/Pfad/zur/XML-Datei.xml")).getRootElement().getAttributeValue("attrib");
```

Ciao
DosCoder


----------



## chmee (9. September 2009)

Ich habe Java leider nie wirklich angefasst. In php gibt es den Befehl *preg_match_all($pattern, $string, $array)*. Das Ergebnis ist ein Array $array, das alle Funde auflistet.

Das wäre das Pattern für *Variablen innerhalb der Anführungszeichen finden*, nach php jedenfalls : *(?<==")[^"]*(?=")*

mfg chmee


----------



## Dany23 (9. September 2009)

DosCoder hat gesagt.:


> Hi,
> was meinst du, mit "den ganzen String in ein Array gelesen bekomme"?
> Außerdem ist in Wikipedia zu lesen, dass JAXP DOM und SAX beinhaltet. Und mit diesen beiden Bibliotheken kann man bequem Attribute auslesen:
> 
> ...




Ja, nur habe ich den Teil den ich zerlegen will ja in einem String und nicht in einer Datei. Auf die restlichen Elemente aus der Datei kann ich direkt zugreifen.


----------



## Thomas Darimont (9. September 2009)

Hallo,

hier ne weitere Möglichkeit,...

```
package de.tutorials;

public class RegexGroupReferenceExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String xml = "<product kodierung=\"A\" nummer=\"100001\" produktmerkmal=\"A\" speicherdatum=\"2004-04-30\" speicheruhrzeit=\"00:00:00\"> </product>";
        
        System.out.println(extract("nummer",xml));
        System.out.println(extract("produktmerkmal",xml));
        System.out.println(extract("speicherdatum",xml));
    }

    private static String extract(String attributeName, String xml) {
        return xml.replaceAll(".*" + attributeName + "\\s*=\"([^\"]*)\".*", "$1");
    }
}
```

Ausgabe:

```
100001
A
2004-04-30
```

Gruß Tom


----------



## Dany23 (9. September 2009)

Hallo,

euch allen vielen Dank für die Unterstützung.

Tom, Deine Lösung sieht auf den ersten Blick genauso aus wie ich es mir vorgestellt habe. 

Hatte es am Ende so realisiert: 
	
	
	



```
public static String getValue(String attribute, String document){
		String value = "";
		String regex = attribute + "=\".*?\"";
		java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regex);
		Matcher m1 = pattern.matcher(document);
		if (m1.find()) {
			value = m1.group();
			int start;
			int end;
			start = value.indexOf("\"") + 1;
			end = value.length() - 1;
			return value.substring(start, end);
		} else
			return "";
}
```
Allerdings auch etwas umständlich.

Grüße
dany


----------

