Suchalgorithmus

Okay.. also hab jetzt mal was gebastelt.. Allerdings ist mir eins noch nicht ganz klar.. Soll der Suchstring von vorne ausgewertet werden? Bsp:

Von vorne:
"bla buo blub" or foo or moep blu
ist gemeint:
(((bla and buo and blub) or foo) or moep) and blu

Richtig? Oder wie wäre die Auswertung in diesem Fall gemeint?
Wenn es so ist hilft dir das vllt:
Java:
import java.util.LinkedList;

public class QueryStringFormat
{
  public static final char CHAR_QUOTE = '"';
  public static final char CHAR_SPACE = ' ';

  public QueryStringFormat()
  {
    //Query String
    String qry = "\"bla blub\" or foo moep";
    
    boolean isQuote = false;
    boolean isSpace = false;
    boolean isFirstQuote = true;

    int quoteStart = -1;
    int quoteEnd = -1;

    LinkedList<int[]> quotes = new LinkedList<int[]>();
    LinkedList<Integer> spaces = new LinkedList<Integer>();

    //Die Leerzeichen und Anfuehrungszeichen erkennen
    for ( int i = 0; i < qry.length(); i++ )
    {
      isQuote = false;
      isSpace = false;

      switch( qry.charAt( i ) )
      {
        case CHAR_QUOTE: isQuote = true; break;
        case CHAR_SPACE: isSpace = true; break;
      }

      if( isQuote && isFirstQuote )
      {
        quoteStart = i;
        isFirstQuote = false;
      }
      else if( isQuote )
      {
        quoteEnd = i;
        isFirstQuote = true;
        quotes.add( new int[]{ quoteStart, quoteEnd } );
      }

      if( isSpace )
      {
        spaces.add( i );
        isSpace = false;
      }
    }

    StringBuffer qryBuf = new StringBuffer( qry );

    //Spaces durch Klammern ersetzen
    for ( int i = 0; i < quotes.size(); i++ )
    {
      int[] actualQuote = quotes.get( i );
      qryBuf.replace( actualQuote[0], actualQuote[0]+1, "(" );
      qryBuf.replace( actualQuote[1], actualQuote[1]+1, ")" );
    }

    int c = 0;
    //Spaces die als AND zu werten sind mit " and " ersetzten
    for ( int i = 0; i < spaces.size(); i++ )
    {
      if( isAndSpace( spaces.get( i ) + c*4, qryBuf ) )
      {
        qryBuf.delete( spaces.get( i ) + c*4, spaces.get( i ) + (c*4) + 1 );
        qryBuf.insert( spaces.get( i ) + c*4, " and " );
        c++;
      }
    }

    //OR's finden und entsprechend Klammern setzten
    LinkedList<Integer> ORs = new LinkedList<Integer>();
    int actualOrOffset = -2;

    while( ( actualOrOffset = qryBuf.indexOf( " or ", actualOrOffset + 2 ) ) > -1 )
    {
      int startFirstTag = getStartOfTag( actualOrOffset, qryBuf );
      int endSecondTag = getEndOfTag( actualOrOffset, qryBuf );

      qryBuf.insert( startFirstTag, "(" );
      qryBuf.insert( endSecondTag, ")" );
    }

    System.out.println( qry );
    System.out.println( qryBuf.toString() );

  }

  private int getStartOfTag( int offset, StringBuffer buf )
  {

    if( buf.charAt( offset - 1 ) != ')' )
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if( buf.charAt( i ) == ' ' )
          return i;
      }
      return 0;
    }
    else
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if ( buf.charAt( i ) == '(' )
          return i;
      }
      return 0;
    }
  }

  private int getEndOfTag( int offset, StringBuffer buf )
  {
    if( buf.charAt( offset + 4 ) != '(' )
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if( buf.charAt( i ) == ' ' )
          return i + 1;
      }
      return 0;
    }
    else
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if ( buf.charAt( i ) == ')' )
          return i + 1;
      }
      return 0;
    }
  }

  private boolean isAndSpace( int offset, StringBuffer qry )
  {
    String before = "";
    String behind = "";

    if( offset > 1 && ( offset + 2 ) < qry.length() )
    {
      before = qry.substring( offset - 2, offset );
      behind = qry.substring( offset + 1, offset + 3 );
    }
    else if( offset > 1 )
    {
      before = qry.substring( offset - 2, offset );
    }
    else
    {
      behind = qry.substring( offset + 1, offset + 3 );
    }

    if( before.equals( "or" ) || behind.equals( "or" ) )
      return false;

    return true;
  }

  public static void main( String[] args ) {
    QueryStringFormat qry = new QueryStringFormat();
  }
}

Danach müsstest du nur noch die einzelnen Suchbegriffe mit den entsprechenden Sql Tags ersetzten..
Bsp: bla -> (LCASE(tabelleA.text) LIKE ‘%bla%’
 
Zuletzt bearbeitet:
Von der Logik her stimmt das.
Vielen Dank schon mal

Ich bekomm aber noch ein Fehler:

"The Type LinkedList is not generic; it cannot be parameterized with arguments <Integer>"
bzw.
"The Type LinkedList is not generic; it cannot be parameterized with arguments <int[]>"
 
Zuletzt bearbeitet:
Hmm.. Hast du Java 5 und Generics aktiviert?
Ansonsten kannst du die Version nehmen - ohne Generics..
Java:
import java.util.LinkedList;

public class QueryStringFormat
{
  public static final char CHAR_QUOTE = '"';
  public static final char CHAR_SPACE = ' ';

  public QueryStringFormat()
  {
    //Query String
    String qry = "\"bla blub\" or foo moep";

    boolean isQuote = false;
    boolean isSpace = false;
    boolean isFirstQuote = true;

    int quoteStart = -1;
    int quoteEnd = -1;

    LinkedList quotes = new LinkedList();
    LinkedList spaces = new LinkedList();

    //Die Leerzeichen und Anfuehrungszeichen erkennen
    for ( int i = 0; i < qry.length(); i++ )
    {
      isQuote = false;
      isSpace = false;

      switch( qry.charAt( i ) )
      {
        case CHAR_QUOTE: isQuote = true; break;
        case CHAR_SPACE: isSpace = true; break;
      }

      if( isQuote && isFirstQuote )
      {
        quoteStart = i;
        isFirstQuote = false;
      }
      else if( isQuote )
      {
        quoteEnd = i;
        isFirstQuote = true;
        quotes.add( new int[]{ quoteStart, quoteEnd } );
      }

      if( isSpace )
      {
        spaces.add( i );
        isSpace = false;
      }
    }

    StringBuffer qryBuf = new StringBuffer( qry );

    //Spaces durch Klammern ersetzen
    for ( int i = 0; i < quotes.size(); i++ )
    {
      int[] actualQuote = (int[]) quotes.get( i );
      qryBuf.replace( actualQuote[0], actualQuote[0]+1, "(" );
      qryBuf.replace( actualQuote[1], actualQuote[1]+1, ")" );
    }

    int c = 0;
    //Spaces die als AND zu werten sind mit " and " ersetzten
    for ( int i = 0; i < spaces.size(); i++ )
    {
      if( isAndSpace( (Integer)spaces.get( i ) + c*4, qryBuf ) )
      {
        qryBuf.delete( (Integer)spaces.get( i ) + c*4, (Integer)spaces.get( i ) + (c*4) + 1 );
        qryBuf.insert( (Integer)spaces.get( i ) + c*4, " and " );
        c++;
      }
    }

    //OR's finden und entsprechend Klammern setzten
    int actualOrOffset = -2;

    while( ( actualOrOffset = qryBuf.indexOf( " or ", actualOrOffset + 2 ) ) > -1 )
    {
      int startFirstTag = getStartOfTag( actualOrOffset, qryBuf );
      int endSecondTag = getEndOfTag( actualOrOffset, qryBuf );

      qryBuf.insert( startFirstTag, "(" );
      qryBuf.insert( endSecondTag, ")" );
    }

    System.out.println( qry );
    System.out.println( qryBuf.toString() );

  }

  private int getStartOfTag( int offset, StringBuffer buf )
  {

    if( buf.charAt( offset - 1 ) != ')' )
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if( buf.charAt( i ) == ' ' )
          return i;
      }
      return 0;
    }
    else
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if ( buf.charAt( i ) == '(' )
          return i;
      }
      return 0;
    }
  }

  private int getEndOfTag( int offset, StringBuffer buf )
  {
    if( buf.charAt( offset + 4 ) != '(' )
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if( buf.charAt( i ) == ' ' )
          return i + 1;
      }
      return 0;
    }
    else
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if ( buf.charAt( i ) == ')' )
          return i + 1;
      }
      return 0;
    }
  }

  private boolean isAndSpace( int offset, StringBuffer qry )
  {
    String before = "";
    String behind = "";

    if( offset > 1 && ( offset + 2 ) < qry.length() )
    {
      before = qry.substring( offset - 2, offset );
      behind = qry.substring( offset + 1, offset + 3 );
    }
    else if( offset > 1 )
    {
      before = qry.substring( offset - 2, offset );
    }
    else
    {
      behind = qry.substring( offset + 1, offset + 3 );
    }

    if( before.equals( "or" ) || behind.equals( "or" ) )
      return false;

    return true;
  }

  public static void main( String[] args ) {
    QueryStringFormat qry = new QueryStringFormat();
  }
}

Gruß
Tobias
 
Vielen Dank für deine Mühe, aber ich bekomm es nicht zum laufen....

Ich bekomm eine "java.lang.UnsupportedClassVersionError" Meldung, wenn ich es starten will :/

Damit kann ich leider nix anfangen.
Was muss ich umstellen ?!

Ich arbeite mit Eclispse, wenn das ein unterschied ist.
 
Ja isses denn wahr ;)
Welche Java Version verwendest du denn? Bei mir läufts sowohl unter Java 5(1.5) als auch unter 1.4.2 ohne Probleme..

Gruß
Tobias
 
Letzter Versuch ^^
Java:
import java.util.LinkedList;

public class QueryStringFormat
{
  public static final char CHAR_QUOTE = '"';
  public static final char CHAR_SPACE = ' ';

  public QueryStringFormat()
  {
    //Query String
    String qry = "\"bla blub\" or foo moep";

    boolean isQuote = false;
    boolean isSpace = false;
    boolean isFirstQuote = true;

    int quoteStart = -1;
    int quoteEnd = -1;

    LinkedList quotes = new LinkedList();
    LinkedList spaces = new LinkedList();

    //Die Leerzeichen und Anfuehrungszeichen erkennen
    for ( int i = 0; i < qry.length(); i++ )
    {
      isQuote = false;
      isSpace = false;

      switch( qry.charAt( i ) )
      {
        case CHAR_QUOTE: isQuote = true; break;
        case CHAR_SPACE: isSpace = true; break;
      }

      if( isQuote && isFirstQuote )
      {
        quoteStart = i;
        isFirstQuote = false;
      }
      else if( isQuote )
      {
        quoteEnd = i;
        isFirstQuote = true;
        quotes.add( new int[]{ quoteStart, quoteEnd } );
      }

      if( isSpace )
      {
        spaces.add( new Integer( i ) );
        isSpace = false;
      }
    }

    StringBuffer qryBuf = new StringBuffer( qry );

    //Spaces durch Klammern ersetzen
    for ( int i = 0; i < quotes.size(); i++ )
    {
      int[] actualQuote = (int[]) quotes.get( i );
      qryBuf.replace( actualQuote[0], actualQuote[0]+1, "(" );
      qryBuf.replace( actualQuote[1], actualQuote[1]+1, ")" );
    }

    int c = 0;
    //Spaces die als AND zu werten sind mit " and " ersetzten
    for ( int i = 0; i < spaces.size(); i++ )
    {
      if( isAndSpace( getInt( spaces.get( i ) ) + c*4, qryBuf ) )
      {
        qryBuf.delete( getInt( spaces.get( i ) ) + c*4, getInt( spaces.get( i ) ) + (c*4) + 1 );
        qryBuf.insert( getInt( spaces.get( i ) ) + c*4, " and " );
        c++;
      }
    }

    //OR's finden und entsprechend Klammern setzten
    int actualOrOffset = -2;

    while( ( actualOrOffset = qryBuf.indexOf( " or ", actualOrOffset + 2 ) ) > -1 )
    {
      int startFirstTag = getStartOfTag( actualOrOffset, qryBuf );
      int endSecondTag = getEndOfTag( actualOrOffset, qryBuf );

      qryBuf.insert( startFirstTag, "(" );
      qryBuf.insert( endSecondTag, ")" );
    }

    System.out.println( qry );
    System.out.println( qryBuf.toString() );

  }

  public int getInt( Object o )
  {
    Integer i = (Integer) o;
    return i.intValue();
  }

  private int getStartOfTag( int offset, StringBuffer buf )
  {

    if( buf.charAt( offset - 1 ) != ')' )
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if( buf.charAt( i ) == ' ' )
          return i;
      }
      return 0;
    }
    else
    {
      for ( int i = offset - 1; i >= 0; i-- )
      {
        if ( buf.charAt( i ) == '(' )
          return i;
      }
      return 0;
    }
  }

  private int getEndOfTag( int offset, StringBuffer buf )
  {
    if( buf.charAt( offset + 4 ) != '(' )
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if( buf.charAt( i ) == ' ' )
          return i + 1;
      }
      return 0;
    }
    else
    {
      for ( int i = offset + 4; i < buf.length(); i++ )
      {
        if ( buf.charAt( i ) == ')' )
          return i + 1;
      }
      return 0;
    }
  }

  private boolean isAndSpace( int offset, StringBuffer qry )
  {
    String before = "";
    String behind = "";

    if( offset > 1 && ( offset + 2 ) < qry.length() )
    {
      before = qry.substring( offset - 2, offset );
      behind = qry.substring( offset + 1, offset + 3 );
    }
    else if( offset > 1 )
    {
      before = qry.substring( offset - 2, offset );
    }
    else
    {
      behind = qry.substring( offset + 1, offset + 3 );
    }

    if( before.equals( "or" ) || behind.equals( "or" ) )
      return false;

    return true;
  }

  public static void main( String[] args ) {
    QueryStringFormat qry = new QueryStringFormat();
  }
}
 
Zuletzt bearbeitet:
Vielen Dank für deine Mühe

Aber ich bekomm leider immer noch die Fehlermeldung

"java.lang.UnsupportedClassVersionError: QueryStringFormat (Unsupported major.minor version 49.0) "

und

"Could not find the main class. Programm will exit."
 
Hmm... Versteh ich nicht wirklich wenn ich ehrlich bin.. Versuch mal das kompilierte Programm auszuführen, hab ich mal angehängt.. Die erste Zeile der Ausgabe ist der Eingabestring (definiert in Zeile 11 im Quellcode) ; die zweite Zeile ist der fertige String..

Gruß
Tobias
 

Anhänge

  • 24828attachment.zip
    2,3 KB · Aufrufe: 25
Das funktioniert einwandfrei....

Code:
"bla blub" or foo moep
((bla and blub) or foo) and moep

Bekomme folgenden Fehler:
Code:
java.lang.UnsupportedClassVersionError: QueryStringFormat (Unsupported major.minor version 49.0)
	at java.lang.ClassLoader.defineClass0(Native Method)
	at java.lang.ClassLoader.defineClass(Unknown Source)
	at java.security.SecureClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.access$100(Unknown Source)
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Exception in thread "main"

Ich kann gar nix mehr dieser Fehlermeldung anfangen :(

PS: Die Quelldatei hast du nicht reingepackt, nur die .class ( weil du meinstes in der 11. Zeile im Quelltext =] )
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück