tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
3
ZUGRIFFE
2548
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Registriert seit
    Jul 2007
    Beiträge
    6
    Moin,

    zunächst möchte ich einmal die Rahmenbedingungen meines Problems schildern.
    Seit Java 1.6 gibt es die Klasse javax.swing.RowFilter, so dass in einem JTable unkompliziert die dargestellten Zeilen nach deren Inhalt gefiltert werden können.

    Existieren in dem jTable beispielsweise die Zeilen {"Mary", "Alison", "Kathy", "Sharon", "Philip", "Isaac"} und man verwendet als Filter den String "s", so werden in dem jTable nur noch die Zeilen {"Alison", "Isaac"} dargestellt. Durch Erweiterung des Filterstrings zu "sa" bleibt nur noch {"Isaac"} übrig. Ein entsprechendes Beispiel stellt uns Sun freundlicherweise in Form der TableFilterDemo zur Verfügung.

    Soweit die Vorgeschichte. Nun folgt die Beschreibung des eigentlichen Problems:

    Das Filtern geschieht durch Aufruf der Methode RowFilter.regexFilter(String regex, int... indices). Bei dem übergebenen String regex handelt es sich um einen regulären Ausdruck. An dieser Stelle sei auf die Klasse Pattern verwiesen. Diese definiert die Muster für reguläre Ausdrücke. Wenn wir zum Beispiel den speziellen Konstruktor "(?i)" vor unserem Filterstring stellen, wird nicht mehr zwischen Groß- und Kleinschreibung unterschieden (case-insensitive). Die Suche nach "(?i)s" liefert dann statt {"Alison", "Isaac"} (s.oben) zusätzlich {"Sharon"}. Alternativ gibt es auch noch den Konstruktor "(?s)" [dotAll], bei dem ein "." für beliebige Zeichen stehen kann. Filtern wir nach "(?is)s.a" erhalten wir als Ergebnis {"Sharon","Isaac"}.

    Ich möchte nun aber den Filter etwas flexibler gestalten. Erweitern wir die Vornamen aus dem DoppelArray "Object[][] data" aus der TableFilterDemo.java folgendermaßen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    private Object[][] data = {
                {"Mary Kate", "Campione",
                 "Snowboarding", new Integer(5), new Boolean(false)},
                {"Alison Hunt", "Huml",
                 "Rowing", new Integer(3), new Boolean(true)},
                {"Kathy Bloom", "Walrath",
                 "Knitting", new Integer(2), new Boolean(false)},
                {"Sharon Stone", "Zakhour",
                 "Speed reading", new Integer(20), new Boolean(true)},
                {"Philip Cipher", "Milne",
                 "Pool", new Integer(10), new Boolean(false)},
                {"Isaac Newton", "Rabinovitch", 
                    "Nitpicking", new Integer(1000), new Boolean(false)}
            };

    Ich bräuchte eine flexible Suche, bei der ich beispielsweise "newton isaac" eingebe/filtere und als Ergebnis die Zeile {"Isaac Newton"} angezeigt bekomme. Ich bräuchte also ein "logisches Und", welches prüft, ob sowohl Substring1 und Substring2 enthalten sind. In der JavaDoc zu Pattern konnte ich bisher nur ein "Oder" finden ("|"). Ein Filtern nach "sa|hi" gibt {"Philip","Isaac"} zurück.

    Hat jemand Erfahrung mit regulären Ausdrücken und kann mir sagen, wie ich ein "logisches Und" realiseren kann, bei dem die Reihenfolge der Substrings im Filterstring egal ist? Wäre super, wenn ich bei der Eingabe "n issac" als Ergebnis {"Isaac Newton"} erhalten würde, aber keine Zeilen, die nur "n" oder "isaac" enthalten.

    Viele Grüße,
    dF
     

  2. #2
    Registriert seit
    Jul 2007
    Beiträge
    6
    Das Problem wurde gelöst durch Permutation der Substrings eines Suchstrings.
    Ist der Suchstring beispielsweise "eine kurze anfrage", werden die Teilbegriffe permutiert und es wird nach Einträgen in den Zellen gesucht, die die Substrings in beliebiger Reihenfolge enthalten.
    Es wird also nach den 3*2*1 (=3!) Möglichkeiten gesucht:
    "eine kurze anfrage"
    "eine anfrage kurze"
    "kurze eine anfrage"
    "kurze anfrage eine"
    "anfrage kurze eine"
    "anfrage eine kurze"

    Damit die Substrings nicht in exakt dieser Reihenfolge auftauchen müssen, wurden die leerzeichen " " durch ".*". Ebenso wurde den Permutationen ein ".*" vor- und nachgestellt. Die Wortgruppen und die möglichen Permutationen wurden zusätzlich noch geklammert.
    Die Permutationen müssen außerdem durch Oder-Verknüpfungen verknüpft werden.
    Es resultiert also quasi folgender regulärer Ausdruck, der die von mir gesuchte Suchanfrage ermöglicht:
    (.*eine.*kurze.*anfrage.*)|(.*eine.*anfrage.*kurze.*)|(.*kurze.*eine.*anfrage.*)|(.*kurze.*anfrage.* eine.*)|(.*anfrage.*eine.*kurze.*)|(.*anfrage.*kurze.*eine.*)

    Die Permutationen benötigen viel Rechenzeit und bei mehr als 6 Substrings ist das schon spürbar (,weswegen bisher nur bis zu 5 Substrings permutiert werden).

    Sollte jemandem irgendwann eine elegantere Lösung einfallen, würde ich mich freuen, diese zu erfahren.
     

  3. #3
    Avatar von zeja
    zeja zeja ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Sep 2006
    Beiträge
    2.962
    Mir scheint es schneller zu sein einen andFilter zu verwenden.

    Für die TableFilterDemo ändere mal die Methode newFilter auf:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    private void newFilter() {
        String[] split = filterText.getText( ).split(" ");
        ArrayList<RowFilter<MyTableModel, Object>> filters = new ArrayList<RowFilter<MyTableModel, Object>>(split.length);
        for (String filterStrg : split) {
            try {
                RowFilter<MyTableModel, Object> rf = RowFilter.regexFilter("(?i)" +
                        filterStrg,
                        0);
                filters.add(rf);
            }
            catch (java.util.regex.PatternSyntaxException e) {
                e.printStackTrace( );
            }
        }
     
        RowFilter<MyTableModel, Object> rf = RowFilter.andFilter(filters);
     
        sorter.setRowFilter(rf);
    }
     

  4. #4
    Registriert seit
    Jul 2007
    Beiträge
    6
    hups... den andFilter() habe ich übersehen. Funktioniert exakt so, wie es sein sollte, nur dass es viel schöner ist, als erst die Permutationen etc aufzustellen.

    Danke für die Hilfe!
     

Ähnliche Themen

  1. Reguläre Ausdrücke
    Von mdo im Forum Java Grundlagen
    Antworten: 6
    Letzter Beitrag: 14.01.11, 16:57
  2. Reguläre Ausdrücke
    Von Ibanese im Forum PHP
    Antworten: 2
    Letzter Beitrag: 06.07.09, 00:17
  3. javax.swing.plaf.FontUIResource: Woher lädt Swing den Font
    Von Deficiency im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 0
    Letzter Beitrag: 17.01.08, 08:38
  4. Reguläre Ausdrücke
    Von Binio im Forum CGI, Perl, Python, Ruby, Power Shell
    Antworten: 1
    Letzter Beitrag: 03.06.07, 23:12
  5. javax.swing.JComboBox
    Von mkoeni1 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 10.01.07, 18:19