Pattern.compile Syntax

Hintertür

Mitglied
Morgen Commy,

ich hab mal folgenden Code gebastelt, weil ich aus nem Text (input, cmd rückgabe) einen bestimmten Teil haben möchte, undzwar ob auf einem Interface DHCP aktiv ist oder nicht.

Kurz: Ich möchte einen Textausschnitt haben

Java:
public String textAuslesen(String input, String startOfInput, String endOfInput){
		Pattern p = Pattern.compile(".*?"+startOfInput+"\\s(.!?*?)\\s"+endOfInput);
		Matcher m = p.matcher(input);
		boolean matches = m.matches();
		int groupCount = m.groupCount();
		return m.group(1);
	}

Funktioniert im moment super! Doch sobald die Parameter folgendermaßen aussehen:

Java:
textAuslesen("Hallo wie geht es dir? Mir geht es sehr gut!", "dir", "gut");
schmeißt er ne Exception: No match found.

Wie bekomme ich jetzt in das Regex
Java:
Pattern.compile(".*?"....
jetzt nocht >!< und >?< hinein, bzw generell Sonderzeichen?

Danke im vorraus!
 
Zuletzt bearbeitet von einem Moderator:
Java:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest
{

	public static String textAuslesen(String input, String startOfInput, String endOfInput)
	{
		Pattern p = Pattern.compile(".*" + startOfInput + "(.*)" + endOfInput + ".*");
		Matcher m = p.matcher(input);
		boolean matches = m.matches();
		int groupCount = m.groupCount();
		
		if(matches && groupCount > 0)
			return m.group(1);
		return "";
	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		System.out.println(textAuslesen("Hallo wie geht es dir? Mir geht es sehr gut!", "dir", "gut"));
	}

}
 
Also ich würd so etwas vorschlagen:
Java:
	public static void main(String args[]){
		String input = "Hallo wie geht es dir? Mir geht es sehr gut!";
                String startOfInput = "dir";
                String endOfInput = "gut";
	        Pattern p = Pattern.compile(".*?"+startOfInput+"(.*?)"+endOfInput);
	        Matcher m = p.matcher(input);

	        while(m.find()){
	        	System.out.println(m.group(1));
	        }

	}

Ein Punkt heißt ja schon beliebiges Zeichen, da musst du nicht die Sonderzeichen extra angeben, die sind schon da mit drin 🙂
 
Zuletzt bearbeitet:
@ Ariol: top! danke deine weise hat funktioniert!! aber wie mache ich das dann mit den whitespaces?

ich will folgenden textausschnitt haben:


sprich: ich will gucken ob DHCP aktiv ist (auf dem bestimmten interface)... wie realisiere ich sowas? da es ja mit tabs und halt den whitespaces ist (inner cmd)

@RySa: danke für die antwort! es lag an den \\s wie ich es herausgefunden hab^^
 
Zuletzt bearbeitet:
Ein Punkt nimmt auch Whitespaces an. d.h wenn du dir das (.*?) ausgeben lässt, und da drinne so etwas enthalten ist
Java:
String s = "                ja              "
, dann brauchst du es ja nur zu trimmen . Also
Java:
String s = "                   Ja                  ";
s = s.trim();

Dann hast du im s nur noch "Ja";
 
es will einfach nicht klappen... hmmm

sprich bei m.matches bricht er leider ab...

hmm ist das so schwer zu realisieren?^^

ich glaube man konnte sich die \r\n ect anzeigen lassen sprich wie in einer zeile...
wisst ihr wie das geht? dann wäre das auch einfacher^^

€dit: so sieht mein code bis jetzt aus:
erstmal der cmd command:

Java:
public String netshellReadDHCP() throws IOException, InterruptedException { 
		Runtime rt = Runtime.getRuntime();
		Process p = null;
		p = rt.exec ("netsh interface ipv4 show addresses");
		InputStream in = p.getInputStream();
		String ausgabe = StringTools.stringFromInputStream(in);
//		System.out.print(ausgabe);
		
		String endausgabe = pm.textAuslesen2(ausgabe, "Konfiguration der Schnittstelle \"Drahtlosnetzwerkverbindung\"", "IP-Adresse", true);
		
		System.out.println(endausgabe);
		//er soll wenns es klappt die endausgabe zurückgeben, und nicht "" ;D
		return "";
                
	}

ich habe bei der pattern methode noch was geändert:

Java:
/**
	 * Diese Methode gibt einen gesuchten Textabschnitt wieder zurück. 
	 * startOfInput und endOfInput sind Case-Sensitiv!
	 * 
     * @autor Christopher Kröncke
	 * @param input Input Text
	 * @param startOfInput Anfang des gesuchten Zwischenabschnittes
	 * @param endOfInput Ende des gesuchten Zwischenabschnittes
	 * @param trimFirstWhitespace Trimmt die whitespaces der vorherigen parameter
	 * @return Gibt den Zwischenabschnitt zurück
	 */
	public String textAuslesen(String input, String startOfInput, String endOfInput, boolean trimInputWhitespace){
		if (trimInputWhitespace){
			input = input.trim();
		}
		Pattern p = Pattern.compile(".*?" + startOfInput + "(.*?)" + endOfInput + ".*?");
		Matcher m = p.matcher(input);
		boolean matches = m.matches();
		int groupCount = m.groupCount();
		if(matches && groupCount > 0){
            return m.group(1);
		}
        return "No Match";
	}

p.s: könnt ihr auch benutzen wenn ihr mögt^^
 
Zuletzt bearbeitet:
Wie wärs wenn du einfach mal nochmal nach "(?i)(?s).*?DHCP aktiviert:.*?(Ja|Nein).*?" suchst. Also so etwas:
Java:
	public static void main(String[] args) {
	String input = "Konfiguration der Schnittstelle \"Drahtlosnetzwerkverbindung\" \n DHCP aktiviert:                  Ja                 \n IP Adresse:                      192.168.178.1        ";
        Pattern p = Pattern.compile("(?i)(?s).*?DHCP aktiviert:.*?(Ja|Nein).*?");
        Matcher m = p.matcher(input);
        while(m.find()){
        	System.out.println(m.group(1));
        }

	}

Ausserdem, (wenn ich mich nicht irre) musst du dem Matcher erstmal sagen "so, jetzt finde mal das nächste, das zutrifft" , also mit Matcher.find() - dann kannst du erst damit arbeiten. Mit .matches() überprüfst du nur ob der mal mindestens 1 Treffer hat, der Matcher ist aber noch nicht an die Stelle der Treffer gegangen, musst du ihm erst mit .find() sagen.

Gruß
 
Zuletzt bearbeitet:
Ohne komplizierte Regex gehts auch so:
Mittels String#split in die einzelnen Zeilen zerlegen und mit String#trim() die Leerzeichen außen herum entfernen.
Dann die Zeilen durchgehen und mit String#startWith die Zeile finden und mit String#endsWith auswerten.

Ist auch nicht viel mehr Code und auch für jemanden ohne Ahnung von Regex verständlich.
 
@ HoaX

Das mag ja sein, allerdings kann sich ein Wert, über mehrere Zeilen strecken und dann würde es nicht mehr so klappen. Und ich finde diese Regex ist gar nicht kompliziert, eher ganz anschaulich. Und falls jemand, wie du sagtest, keine Ahnung von Regex hat, dann wäre es jetzt der richtige Zeitpunkt sich mit denen auseinander zu setzen, weil die echt immer wieder zu gebrauchen sind.

Außerdem, nehme ich an, dass der TO eigentlich immer die Werte hinter name: haben möchte, also z.B IP Adresse: 192......., dann kann er einfach mal aus meinem letzten Beispiel ne Methode machen, der der Name übergeben wird, und dann einfach mal so gesucht wird: "(?i)(?s).*?"+name+":.*?(Ja|Nein).*?" , somit braucht er nur den kompletten String zu übergeben und den Namen. Das ist aber alles eine Sache der Implementierung.
 
Java:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest
{

	public static boolean isDHCPEnabled(String input)
	{
		Pattern p = Pattern.compile("(?i)(?s).*DHCP aktiviert\\:\\s*(Ja|Nein).*");
		Matcher m = p.matcher(input);

		boolean matches = m.matches();
		if(!matches)
			return false;
		
		int groupCount = m.groupCount();
		String dhcpState = "Nein";
		if(groupCount > 0)
			dhcpState = m.group(1);
		return dhcpState.equals("Ja");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		System.out.println(isDHCPEnabled("Text davor\n    DHCP aktiviert:                       Nein\nText danach\n"));
		System.out.println(isDHCPEnabled("Text davor\n    DHCP aktiviert:                       Ja\nText danach\n"));
		System.out.println(isDHCPEnabled("Blub"));
	}

}

Works for me.

@RySa: Find brauchst du nicht, wenn du nur einmal prüfst:
http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#matches(java.lang.String hat gesagt.:
If a pattern is to be used multiple times, compiling it once and reusing it will be more efficient than invoking this method each time.
 
Hab ja gesagt "wenn ich mich nicht irre" 😛 anscheinend hab ich mich geirrt 🙂 war aber so ne vermutung warum er bei ihm immer bei matches da "aufgegeben" hat 🙂 ich benutze allerding immer das find(), habe mir so angewöhnt und konnte mich bisher noch nicht beschweren 🙂 Also, die beiden Varianten funktionieren. Jetzt warten wa nur noch auf den TO ^^
 
so mädels,

habe beide varianten ausprobiert ;D das problem: ich weiß bei Ariol nicht was in den input soll... weil der input ja folgendes ist:

Konfiguration der Schnittstelle "Drahtlosnetzwerkverbindung"
DHCP aktiviert: Ja
Schnittstellenmetrik: 50

Konfiguration der Schnittstelle "LAN-Verbindung"
DHCP aktiviert: Ja
IP-Adresse: 192.168.160.112
Subnetzpräfix: 192.168.160.0/24 (Maske 255.255.255.0)

Standardgateway: 192.168.160.11
Gatewaymetrik: 0
Schnittstellenmetrik: 10

Konfiguration der Schnittstelle "Loopback Pseudo-Interface 1"
DHCP aktiviert: Nein
IP-Adresse: 127.0.0.1
Subnetzpräfix: 127.0.0.0/8 (Maske 255.0.0.0)
Schnittstellenmetrik: 50

soll ich das ganze in den input dann reinpacken? sorry das ich mich so blöd anstelle :/

€dit: mist er nimmt die whitespaces hier im forum nicht an °-° siehe bild oben 😉
 
Wenn du es ganz genau haben willst:
Java:
    public static void main(String[] args) {
    String input = "Konfiguration der Schnittstelle \"Drahtlosnetzwerkverbindung\" \n DHCP aktiviert:                  Ja                 \n IP Adresse:                      192.168.178.1        "; //usw, halt der ganze input von dir
    String start = "\"Drahtlosnetzwerkverbindung\"";
    String end = "IP Adresse";
        Pattern p = Pattern.compile("(?i)(?s)"+start+".*?DHCP aktiviert:.*?(Ja|Nein).*?"+end);
        Matcher m = p.matcher(input);
        while(m.find()){
            System.out.println(m.group(1));
        }
 
    }
 
ich danke Ariol und dir RySe auch besonders!! funktioniert jetzt 🙂
folgendes ist jetzt mein programmcode:

Java:
public String dhcp(String input, String interfaceName) throws IOException, InterruptedException{
            Pattern pattern = Pattern.compile("(?i)(?s)\""+interfaceName+"\".*?DHCP aktiviert:.*?(Ja|Nein).*?IP-Adresse");
            Matcher m = pattern.matcher(input);
            boolean matches =m.find();
            int groupCount = m.groupCount();
            if(matches && groupCount > 0){
                  if(m.group(1).equals("Ja")){
                        return "DHCP-On";
                  }else{
                        return "DHCP-Off";
                  }
            }
        return "No Match";
      }

und die methode funktioniert super auf DHCP 🙂 danke nochmal leute!
 
Eieiei, die armen nicht-Windows-User und die, die nicht deutsch eingestellt haben... 😀
Man könnte auch ganz ohne kompliziertem Regex auskommen und den Scanner nutzen 😉
Java:
		Scanner sc = new Scanner(input);
		while (sc.findWithinHorizon("DHCP aktiviert:", 0) != null) {
			System.out.println(sc.nextLine().trim());
		}
oder evtl. um doch noch ein wenig sprachunabhängiger zu sein (ka ob da bei englisch so etwas wie DHCP activated steht :bahnhof:= ) eben doch ein wenig Regex - so etwas wie:
Java:
sc.findWithinHorizon("DHCP .+?:", 0) != null) {
 
Zuletzt bearbeitet:

Zurück
Oben