# Tokens auf regex prüfen



## hispeedsurfer (31. Oktober 2006)

Hallo,

ich habe verschiedenartige Tokens und suche einen passenden regulären Ausdruck, um diese zu splitten.


Die Tokens können sein: -50-100°C,      +/-5,3mV    <-das letzte ist ein float, also nicht 5 und 3

rauskommen soll: -50-100,    °C,    +/-,     5,3,    mV <- genau so wie oben



Kann mir da jemand helfen, welchen regulären Ausdruck ich dafür benögtige, wenn eine passender überhaupt existiert?


Danke
Andreas


----------



## zeja (31. Oktober 2006)

Nicht ganz das was du suchst, aber mit split kenne ich mich auch nicht so gut aus. Aber das hier funktioniert:


```
package de.tutorials;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author zeja
 */
public class PatternMatching {
	
	private static final String DELIM = "(-[0-9]*-[0-9]*)(°C), (\\+/-)([0-9]*,[0-9]*)(mV)";
	private static final Pattern PATTERN = Pattern.compile(DELIM);
	
	public static List<String> splitData(String data){
		ArrayList<String> list = new ArrayList<String>();
		Matcher m = PATTERN.matcher(data);
		if(m.matches()){
			for(int i = 1; i <= m.groupCount( ); i++){
				String group = m.group(i);
				list.add(group);
			}
		}
		return list;
	}
	
	public static void main(String[] args) {
		List<String> data = splitData("-50-100°C, +/-5,3mV");
		System.out.println(data);
	}
}
```

Ausgabe:

```
-50-100
°C
+/-
5,3
mV
```


----------



## hispeedsurfer (31. Oktober 2006)

Hallo zeja,

Danke für deine Antwort. Versuche immernoch hinter die Logik von Pattern zu steigen.

So ganz war das nicht gemeint. Da habe ich mich wohl nicht deutlich genug ausgedrückt (-;.

Es sind einzelne Strings wie:

-50-100°C
+/-5,3mV 

Kann aber auch mal nur -50 oder +250 sein. Ich habe gehoft das ich einen Verknüpfung mehrer regulärer Ausdrücke vornehmen kann, bei denen dann einer auf das Muster passt.

Es soll quase jeder einzelne String auf ein Pattern geprüft werden.

Wäre super wenn du noch eine Idee hättest.


Danke
Andreas


----------



## zeja (31. Oktober 2006)

So ist es vielleicht ein wenig übersichtlicher und erkennt nun auch sämtliche Dezimalzahlen und Ganze Zahlen mit und ohne Vorzeichen und auch in Bereichen, sowie mit Einheit.


```
package de.tutorials;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author zeja
 */
public class PatternMatching {
  
  //Beliebige Ganze Zahl: z.B. 50
  private static final String AN_INT = "[0-9]*";
  //Beliebige Dezimalzahl (oder ganze Zahl): z.B. 50 oder 99,9
  private static final String A_FLOAT = AN_INT + "(?:,"+AN_INT + ")?";
  //Vorzeichen +/-
  private static final String PLUS_MINUS = "\\+/-";
  //Eines der Vorzeichen +, - oder +/-
  private static final String SIGNS = "(?:\\+)|(?:-)|(?:"+PLUS_MINUS+")";
  //Beliebige Dezimalzahl mit Vorzeichen, z.B. +/- 50,5 oder -100
  private static final String SIGNED_FLOAT = "(?:"+ SIGNS + ")?" + A_FLOAT;
  //Beliebiger Dezimalzahl Bereich z.B. -50-100
  private static final String FLOAT_RANGE = SIGNED_FLOAT + "(?:-"+ SIGNED_FLOAT + ")?";
  //Ein Einheit °C oder mV
  private static final String UNIT = "(?:°C|mV)";
  //Ein Dezimalzahlbereich mit Einheit
  private static final String FLOAT_RANGE_WITH_UNIT = "(" + FLOAT_RANGE + UNIT + ")";
  private static final String DELIM = FLOAT_RANGE_WITH_UNIT + ", " + FLOAT_RANGE_WITH_UNIT;
  
  private static final Pattern PATTERN = Pattern.compile(DELIM);
  
  public static List<String> splitData(String data){
    ArrayList<String> list = new ArrayList<String>();
    Matcher m = PATTERN.matcher(data);
    if(m.matches()){
      for(int i = 1; i <= m.groupCount( ); i++){
        String group = m.group(i);
        list.add(group);
      }
    }
    return list;
  }
  
  public static void main(String[] args) {
    System.out.println(PATTERN.pattern( ));
    List<String> data = splitData("-50-100°C, +/-5,3mV");
    System.out.println(data);
  }
}
```

Bei solch langen Ausdrücken ist es auch sinnvoll diese aus Einzelteilen zusammenzusetzen. Der gesamte Ausdruck wird auch zu Beginn ausgegeben und ist absolut nicht mehr lesbar.


----------



## hispeedsurfer (31. Oktober 2006)

Hallo zeja,

vielen Danke für deine Mühe. 
Wenn ich das Beispiel laufen lasse, ist die Ausgabe die selbe wie die Eingabe. Keine Separierung der Daten.

Das Ergebnis sieht bei mir so aus:

[-50-100°C, +/-5,3mV]

Evtl noch eine Idee?


Gruß
Andreas


----------



## zeja (31. Oktober 2006)

Guck dir die eckigen Klammern drumherum an. Du kriegst eine Liste zurück mit den beiden Elementen

 -50-100°C
 +/-5,3mV
und die Liste wird durch System.out.println wie folgt ausgegeben [<element1>, <element2>] daher sieht es im ersten Moment so aus, als wenn nichts getan wurde.


----------



## hispeedsurfer (31. Oktober 2006)

Ich glaub es fehlt mir an der passenden Ausdrucksweise oder es fehlt mir sonst irgendwo.

In deinem Bsp ist die Eingabe:

"-50-100°C, +/-5,3mV"


und die Ausgabe:

[-50-100°C, +/-5,3mV]
also:

-50-100°C
+/-5,3mV


aber rauskommen soll, wie du  schon am Anfang richtig erkannt hattest:

-50-100
°C
+/-
5,3
mV
also:
[-50-100, °C, +/-, 5,3, mV]
Sorry das ich dich so nerve...

Lg
Andreas


----------



## zeja (31. Oktober 2006)

Dann beschäftige dich doch ein wenig selber mal damit. Das ist nun nicht mehr schwer hinzubekommen.

Das was am Ende vom PatternMatcher ausgegeben wird steht in Runden Klammern, wie eben im Beispiel FLOAT_RANGE_WITH_UNIT. Also alles was du ausgegeben haben willst mit solchen Klammern einfassen und mal das Javadoc von Pattern lesen, da steht alles drin was man braucht. Versuche einfach meinen Code zu verstehen.


----------



## hispeedsurfer (1. November 2006)

>> Dann beschäftige dich doch ein wenig selber mal damit. 

Das versuche ich schon die ganze Zeit, komme aber nicht klar, deshalb habe ich ja hier ins Forum gepostet.

Wenn ich mal probehalber versuche dein Beispiel anzuwenden hört es schon auf wenn ich versuche nur °C und mV auszugeben

Bei Regex ".*(°C|mV)" ist die Ausgabe [mV], °C aber nicht
Bei Regex ".*(?:°C|mV)" habe ich gar kein Ergebnis [].

Wie  das den mit den non-capturing groups?

Gruß
Andreas


----------



## zeja (2. November 2006)

> Bei Regex ".*(?:°C|mV)" habe ich gar kein Ergebnis [].
> 
> Wie das den mit den non-capturing groups?



Gruppen die mit (?: beginnen sind non-capturing groups. Das bedeutet alles was dort zwischen den Klammern ( ) steht wird zwar erkannt, aber nicht als eigenes Ergebnis vom Matcher ausgegeben.

Besser hab ichs gerade nicht hinbekommen. Kenne mich damit auch nicht wirklich gut aus.


```
package de.tutorials;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author zeja
 */
public class PatternMatching {
  
  //Beliebige Ganze Zahl: z.B. 50
  private static final String AN_INT = "[0-9]*";
  //Beliebige Dezimalzahl (oder ganze Zahl): z.B. 50 oder 99,9
  private static final String A_FLOAT = AN_INT + "(?:,"+AN_INT + ")?";
  //Vorzeichen +/-
  private static final String PLUS_MINUS = "\\+/-";
  //Eines der Vorzeichen +, - oder +/-
  private static final String SIGNS = "\\+|-|"+PLUS_MINUS+"";
  //Beliebige Dezimalzahl mit Vorzeichen, z.B. +/- 50,5 oder -100
  private static final String SIGNED_FLOAT = "(?:"+ SIGNS + ")?" + A_FLOAT;
  //Beliebiger Dezimalzahl Bereich z.B. -50-100
  private static final String FLOAT_RANGE = SIGNED_FLOAT + "-"+ SIGNED_FLOAT;
  //Ein Einheit °C oder mV
  private static final String UNIT = "(?:°C|mV)";
  //Ein Dezimalzahlbereich mit Einheit
  private static final String FLOAT_RANGE_WITH_UNIT = "(?:(" + FLOAT_RANGE  +")|(?:(" + SIGNS + ")(" + A_FLOAT +")))("+ UNIT + ")";
  private static final String DELIM = FLOAT_RANGE_WITH_UNIT + ", " + FLOAT_RANGE_WITH_UNIT;
  
  private static final Pattern PATTERN = Pattern.compile(DELIM);
  
  public static List<String> splitData(String data){
    ArrayList<String> list = new ArrayList<String>();
    Matcher m = PATTERN.matcher(data);
    if(m.matches()){
      for(int i = 1; i <= m.groupCount( ); i++){
        String group = m.group(i);
        //nicht schön aber geht
       if(group != null){
        	list.add(group);
        }
      }
    }
    return list;
  }
  
  public static void main(String[] args) {
    System.out.println(PATTERN.pattern( ));
    List<String> data = splitData("-50-100°C, +/-5,3mV");
    System.out.println(data);
  }
}
```


----------



## hispeedsurfer (29. November 2006)

Danke zeja

nach einigem rumprobieren und deinen Vorlagen hab ich nun endlich hinbekommen.



Gruß
Andreas


----------

