2016-04-04 12 views
1

Ich habe Passende auf Wildcard-Muster vor kurzem gearbeitet, wo das Format:Java Wildcard Separator

"http(yyy|xxx|zzz|fssadasd|asdasd|asdasdas|asdasdasd|://)www.w3schools(.com|.org|.net).*" 

für die Daten:

http://www.w3schools.com/html/tryit.asp?filename=tryhtml_default

ich ein Muster entwickelt haben Funktion Anpassung auszuführen, wenn Das Format ist einzeln geklammert (mehrere oder Operatoren). Wie kann ich alle möglichen Kombinationen des oben genannten Formats speichern (mehrere Klammern und mehrere Operatoren).

Einige der möglichen Kombinationen:

httpyyyw3schools.com *

httpxxxw3schools.com *

httpzzzw3schools.com *

httpyyyw3schools.net *

.... httpxxxw3schools.net. *

httpzzzw3schools.net. * Etc.,

Bitte lassen Sie mich wissen, wenn die Frage noch unklar ist?

Die Pattern-Matching-Funktion ist:

import java.util.*; 
import java.util.regex.Pattern; 
import java.util.regex.Matcher; 
public class wildcardtest 
{ 
    public static void main(String[] args) 
    { 

    test("h*p(://|xxx)ww*", "http://www.w3schools.com/html/tryit.asp?filename=tryhtml_default"); 
    test("h*p(yyy|://)ww*", "http://www.w3schools.com/html/tryit.asp?filename=tryhtml_default"); 
    test("h*p(yyy|xxx|zzz|fssadasd|asdasd|asdasdas|asdasdasd|://)ww*", "http://www.w3schools.com/html/tryit.asp?filename=tryhtml_default"); 
    test("ge?ks*", "geeksforgeeks"); 
    test("g*k", "gee"); 
    test("*pqrs", "pqrst"); 
    test("abc*bcd", "abcdhghgbcd"); 
    test("abc*c?d", "abcd"); 
    test("*c*d", "abcd"); 
    test("*?c*d", "abcd"); 
    test("*", "abcd"); 
    test("?", "a"); 
    } 

    static boolean matches(String format, String data) { 

     if(format.contains("|")) 
     { 

      int openpos = format.indexOf("("); 
      int closepos = format.indexOf(")"); 

      String match = ""; 
      Pattern p = Pattern.compile("\\((.*?)\\)"); 
      Matcher m = p.matcher(format); 

       while(m.find()) 
       { 
        match = m.group(1); 
       } 

      String after = format.substring(closepos+1); 
      String[] spliiter = match.split(Pattern.quote("|")); 

      for(int i = 0;i<spliiter.length;i++) 
      { 
       StringBuilder before = new StringBuilder(format.substring(0,openpos)); 
       before.append(spliiter[i]).append(after);  

       if (matches(before.toString(),data)) { 
        return true; 
       } 

      }   
      return false; 
     } 



    if (format.length() == 0 && data.length() == 0) 
     return true; 

    if (format.length() == 1 && format.charAt(0) == '*') 
     return true; 

    if (format.length() == 0 && data.length() > 0) 
     return false; 

    if (format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0) 
     return false; 

    if (format.charAt(0) == '?' || format.charAt(0) == data.charAt(0)) 
     return matches(format.substring(1), data.substring(1)); 

    if (format.charAt(0) == '*') 
     return matches(format.substring(1), data) || matches(format, data.substring(1)); 

    return false; 
} 

    static void test(String first, String second) 
    { 
     System.out.println(matches(first, second)); 
    } 

} 
+0

Was meinst du mit * Wie bekomme ich zu speichern *? Wenn "www." optional ist, verwenden Sie '(?: Www \.)?' Um ein literales '.' Zu erhalten, müssen Sie '\ .' im Muster verwenden. In Bezug auf die Leistung, '(.com | .org | .net)' verliert zu '(\. (?: com | org | net))' –

+0

@ WiktorStribiżew Ich muss diese Kombinationen in einer Liste speichern, so dass ich kann Übergeben Sie es an meine Wildcard-Muster-Matching-Funktion, und das oben angegebene Format ist nur ein Beispiel für einen Testfall. Das Hauptziel ist die Annahme mehrerer Klammern mit mehreren ODER-Bedingungen. –

+1

Dann zeigen Sie bitte Ihren Code. –

Antwort

0

Ich bin nicht bekannt, dass Bibliothek Methode, die dies tun wird.

Betrachten wir das allgemeine Problem:

Schreiben Sie eine Funktion, alle möglichen Strings aufzulisten, die einen bestimmten Regex übereinstimmen.

Wenn der Regex ein * enthält, das Ergebnis davon wird eine unendliche Menge von Strings sein. (Oder, wenn wir uns auf Java beschränken String Objekt wird die Menge endlich sein, aber unglaublich groß zu repräsentieren.)

Wenn wir Funktion beschränken, um nur die Veränderungen zu decken, dann erhalten wir eine endliche Menge von möglichen Zeichenfolgen. Allerdings:

  • , die Funktionalität ist nicht allgemein nützlich und (AFAIK) niemand gedacht hat, es als Bibliothek Methode zu implementieren
  • es sei denn, Ihre regex Sprache * ausschließt, die Testfälle erzeugen Sie möglicherweise nicht ausreichend die Abdeckung Funktionalität, die Sie versuchen zu testen.

Aber könnten Sie es implementieren?

Nun ja, Sie könnten. Aber Sie müssten einen Parser schreiben, um die Input-Regexes zu analysieren, um dies zu tun. Mein Bauchgefühl ist, dass Sie viel Zeit damit verbringen würden, diesen Parser zu programmieren und zu testen. Mehr Zeit als das Schreiben von Testfällen mit handgeschriebenen/fest verdrahteten Zeichenketten, die mit jedem Beispielregex übereinstimmen.