Regulären Ausdruck in normalen Java-Code umwandeln

NicoRyl

Mitglied
Hallo zusammen,

kann mir jemand helfen diesen regulären Ausdruck in normalen Java Code umzuwandeln? Ich hab schon eine Vorstellung wie das gehen könnte, allerdings weiß ich nicht wie ich es umsetzten kann.
Vielen Dank schonmal im Voraus!

Code:
"^SELECT\\s+(\\*?[A-Za-z0-9,\\s]*)\\s+FROM\\s+[A-Za-z0-9]+(\\s+WHERE\\s+([A-Za-z0-9])+\\s+([=<>]|LIKE)\\s['][A-Za-z0-9\\s]+['])?;$"
 
Ein passender String soll mit "SELECT " beginnen.

Also if (string.startsWith("SELECT ")){.

Dann schneidest Du das erledigte Stück ab:
string = string.substring("SELECT ".length);

Dann erwartest Du entweder das Sternchen (Asterisk) oder eine Feldliste.

Steht am Anfang das Sternchen, dann in entsprechenden if-Block laufen und Sternchen abschneiden.

Alternativer if-Block für die Feld-Liste, eventuell in einer eigenen Methode.

usw.
 
Das ist komplex. Bist du dir sicher dass du nicht einen Parser willst, zum Beispiel ANTLR welches bereits fertige Grammatik fuer verschiedene SQL-DIalekte hat. Ich habe noch nie mit ANTLR gearbeitet, aber der wird dir das vermutlich in einen Baum umsetzen den du dann nach selbst gebauten Regeln validieren kannst.

Alternativ...was hast du vor? Erlaubst du Benutzereingabe als SQL?
 
So einen Regulären Ausdruck kann man unterteilen um zu sehen, was alles wie erlaubt ist:
Code:
^SELECT\\s+(\\*?[A-Za-z0-9,\\s]*)\\s+FROM\\s+[A-Za-z0-9]+(\\s+WHERE\\s+([A-Za-z0-9])+\\s+([=<>]|LIKE)\\s['][A-Za-z0-9\\s]+['])?;$


^SELECT
\\s+
(\\*?[A-Za-z0-9,\\s]*)
\\s+
FROM
\\s+
[A-Za-z0-9]+
(\\s+WHERE\\s+([A-Za-z0-9])+\\s+([=<>]|LIKE)\\s['][A-Za-z0-9\\s]+['])?
;$

Ich habe es erst einmal in Blöcke aufgeteilt, die nacheinander vorhanden sein müssen. Die kann man der Reihe nach prüfen bzw. weiter unterteilen:

^SELECT wäre also: Startet der String mit SELECT?
\\s+ -> ein oder mehr Whitespaces
FROM
...

Da kannst Du also den String Stück für Stück vorgehen.

Wenn Du an Teile kommst, die ein | haben, dann musst du halt mehrere Dinge prüfen um zu sehen, ob eins zutrifft.
([=<>]|LIKE) wäre also ein = oder ein < oder ein > oder eben das LIKE.

So kannst Du DIESEN regulären Ausdruck für Dich in Code nachbilden.

Die Frage ist aber, wie sinnvoll das alles ist. Folgende Dinge sind evtl. noch interessant in dem Zusammenhang:

a) Falls es um generelles Ausführen beliebiger Regulärer Ausdrücke gehen sollte, dann wäre ggf. Sinnvoll, sich eine der Implementierungen anzusehen. (Aber das dürfte nicht der Fall sein, so ich Dich richtig verstanden habe!)

b) Es gibt Parser (Das ist ein Bestandteil beim Compiler), der so Ausdrücke auswertet. Und da kann man dann auch auf Generatoren zurück greifen. Dann muss man selbst nur noch die Regeln der Sprache entsprechend aufführen und dann wird einem ein Parser generiert. Die Parsergeneratoren, die wohl am weitesten verbreitet sind, dürften Yacc und GNU Bison sein. Im Java Umfeld wäre dann z.B. JavaCC https://javacc.github.io/javacc/ interessant.
Das ist aber ein breites und komplexes Thema, aber evtl. willst Du ja auch in die Richtung gehen.

c) Hier ist mir Robert zuvor gekommen: Wenn es nur speziell um die Validierung von SQL geht: Da gibt es ja auch fertiges 🙂
 
Das ist komplex. Bist du dir sicher dass du nicht einen Parser willst, zum Beispiel ANTLR welches bereits fertige Grammatik fuer verschiedene SQL-DIalekte hat. Ich habe noch nie mit ANTLR gearbeitet, aber der wird dir das vermutlich in einen Baum umsetzen den du dann nach selbst gebauten Regeln validieren kannst.

Alternativ...was hast du vor? Erlaubst du Benutzereingabe als SQL?
So einen Regulären Ausdruck kann man unterteilen um zu sehen, was alles wie erlaubt ist:
Code:
^SELECT\\s+(\\*?[A-Za-z0-9,\\s]*)\\s+FROM\\s+[A-Za-z0-9]+(\\s+WHERE\\s+([A-Za-z0-9])+\\s+([=<>]|LIKE)\\s['][A-Za-z0-9\\s]+['])?;$


^SELECT
\\s+
(\\*?[A-Za-z0-9,\\s]*)
\\s+
FROM
\\s+
[A-Za-z0-9]+
(\\s+WHERE\\s+([A-Za-z0-9])+\\s+([=<>]|LIKE)\\s['][A-Za-z0-9\\s]+['])?
;$

Ich habe es erst einmal in Blöcke aufgeteilt, die nacheinander vorhanden sein müssen. Die kann man der Reihe nach prüfen bzw. weiter unterteilen:

^SELECT wäre also: Startet der String mit SELECT?
\\s+ -> ein oder mehr Whitespaces
FROM
...

Da kannst Du also den String Stück für Stück vorgehen.

Wenn Du an Teile kommst, die ein | haben, dann musst du halt mehrere Dinge prüfen um zu sehen, ob eins zutrifft.
([=<>]|LIKE) wäre also ein = oder ein < oder ein > oder eben das LIKE.

So kannst Du DIESEN regulären Ausdruck für Dich in Code nachbilden.

Die Frage ist aber, wie sinnvoll das alles ist. Folgende Dinge sind evtl. noch interessant in dem Zusammenhang:

a) Falls es um generelles Ausführen beliebiger Regulärer Ausdrücke gehen sollte, dann wäre ggf. Sinnvoll, sich eine der Implementierungen anzusehen. (Aber das dürfte nicht der Fall sein, so ich Dich richtig verstanden habe!)

b) Es gibt Parser (Das ist ein Bestandteil beim Compiler), der so Ausdrücke auswertet. Und da kann man dann auch auf Generatoren zurück greifen. Dann muss man selbst nur noch die Regeln der Sprache entsprechend aufführen und dann wird einem ein Parser generiert. Die Parsergeneratoren, die wohl am weitesten verbreitet sind, dürften Yacc und GNU Bison sein. Im Java Umfeld wäre dann z.B. JavaCC https://javacc.github.io/javacc/ interessant.
Das ist aber ein breites und komplexes Thema, aber evtl. willst Du ja auch in die Richtung gehen.

c) Hier ist mir Robert zuvor gekommen: Wenn es nur speziell um die Validierung von SQL geht: Da gibt es ja auch fertiges 🙂
Das Ziel meines Projekts ist es, zwei Programme zu schreiben (das eine mit Regex, das andere ohne), die genau das Selbe können und diese zu vergleichen. Das heißt es geht in erster Linie nicht um den SQL-Validator an sich und dass dieser perfekt ist, sondern eher um den Vergleich. 🙂
 
Das Ziel meines Projekts ist es, zwei Programme zu schreiben (das eine mit Regex, das andere ohne), die genau das Selbe können und diese zu vergleichen.
Dann wirklich den Regulären Ausdruck in kleine Bausteine unterteilen. Da kann man dann sehr schön mit Methoden arbeiten.
Beispiel:
int checkText(String testString, int currentPos, String serachString)
=> schaut, ob ein gegebene Text (searchString) an der genannten Position im testString ist. So dies der Fall ist, wird die Position nach dem testString zurück gegeben. Ist der Text nicht vorhanden, dann wird -1 zurück gegeben.

Das würde ich so wählen (Über den Namen müsste man ggf. noch nachdenken), denn so kann man ganz viele Methoden schreiben. Zusätzlich könnte man noch die Anzahl hinzu fügen (Also 1mal, ?, + und * sind da ja mögliche Angaben!)
Und man kann statt searchString auch andere Dinge nehmen, also z.B. ein char[] als Parameter um Zeichen zu prüfen.

Das wäre dann jetzt noch sehr einfach. Es wird komplexer, falls Du noch weitere Dinge einbaust ... non greedy Matcher z.B., denn dann musst Du wissen, wie es danach aufhören könnte ...

Aber das geht alles und wird nicht einmal so komplex.
 
Dann wirklich den Regulären Ausdruck in kleine Bausteine unterteilen. Da kann man dann sehr schön mit Methoden arbeiten.
Beispiel:
int checkText(String testString, int currentPos, String serachString)
=> schaut, ob ein gegebene Text (searchString) an der genannten Position im testString ist. So dies der Fall ist, wird die Position nach dem testString zurück gegeben. Ist der Text nicht vorhanden, dann wird -1 zurück gegeben.

Das würde ich so wählen (Über den Namen müsste man ggf. noch nachdenken), denn so kann man ganz viele Methoden schreiben. Zusätzlich könnte man noch die Anzahl hinzu fügen (Also 1mal, ?, + und * sind da ja mögliche Angaben!)
Und man kann statt searchString auch andere Dinge nehmen, also z.B. ein char[] als Parameter um Zeichen zu prüfen.

Das wäre dann jetzt noch sehr einfach. Es wird komplexer, falls Du noch weitere Dinge einbaust ... non greedy Matcher z.B., denn dann musst Du wissen, wie es danach aufhören könnte ...

Aber das geht alles und wird nicht einmal so komplex.
Ich habe das jetzt folgendermaßen gemacht. Da sind noch einige Fehler drin, aber wäre das eine Möglichkeit, oder bin ich da komplett auf dem falschen Weg?

Java:
public class SQLValidator {

  private static final char[] ALLOWED_CHARACTERS = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ', ','};

  private static final String[] ALLOWED_CHARACTERS_FOR_WHERE = {"<", ">", "=", "LIKE"};


  public boolean isValidSQL(String sql) {
    if(sql.startsWith("SELECT ")){
      return true;
    }

    if(sql.substring("SELECT ".length()).startsWith(ALLOWED_CHARACTERS.toString())) {
      return true;
    }

    if(sql.substring(ALLOWED_CHARACTERS[].length()).startsWith("FROM ")){
      return true;
    }

    if(sql.substring("FROM ".length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return true;
    }

    if(sql.endsWith(";")){
      return true;
    }
    else if(sql.substring(ALLOWED_CHARACTERS[].length()).startsWith("WHERE ")){
      return true;
    }

    if(sql.substring("WHERE ".length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return true;
    }

    if(sql.substring(ALLOWED_CHARACTERS[].length()).startsWith(ALLOWED_CHARACTERS_FOR_WHERE)){
      return true;
    }
    
    if(sql.substring(ALLOWED_CHARACTERS_FOR_WHERE[].length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return true;
    }
    
    if(sql.endsWith(";")){
      return true;
    }
    return false;
  }
}
 
Die Logik stimmt so nicht. Bei dem Code würde es ausreichen, wenn eine Bedingung erfüllt ist. Und das willst Du nicht. Und einige Checks sind nicht ok würde ich behaupten ohne genau hin geschaut zu haben... (Daher mag ich Deine Logik auch nicht verstanden haben bei dem einen oder anderen Check ...)

Besser wird es, wenn Du die Logik umdrehst, also:
Wenn es nicht mit SELECT anfängt, dann return false.

Und Du brauchst auf jeden Fall immer eine vernünftige Position, aber der du prüfst. Also z.B. erst einmal bei 0 das Select prüfen...
Aber sobald es um mehrere mögliche Längen geht:
SELECT * FROM test;
SELECT someField FROM test;
SELECT someFieldWithVeryLongName FROM test;
==> Der Anfang vom FROM kann also nicht irgendwas festes sein wie die Länge eines Arrays, das Du hast ...
 
Die Logik stimmt so nicht. Bei dem Code würde es ausreichen, wenn eine Bedingung erfüllt ist. Und das willst Du nicht. Und einige Checks sind nicht ok würde ich behaupten ohne genau hin geschaut zu haben... (Daher mag ich Deine Logik auch nicht verstanden haben bei dem einen oder anderen Check ...)

Besser wird es, wenn Du die Logik umdrehst, also:
Wenn es nicht mit SELECT anfängt, dann return false.

Und Du brauchst auf jeden Fall immer eine vernünftige Position, aber der du prüfst. Also z.B. erst einmal bei 0 das Select prüfen...
Aber sobald es um mehrere mögliche Längen geht:
SELECT * FROM test;
SELECT someField FROM test;
SELECT someFieldWithVeryLongName FROM test;
==> Der Anfang vom FROM kann also nicht irgendwas festes sein wie die Länge eines Arrays, das Du hast ...
Besser wird es, wenn Du die Logik umdrehst, also:
Wenn es nicht mit SELECT anfängt, dann return false.
Wie könnte man das denn schreiben?
 
Wie könnte man das denn schreiben?

Java:
if(!sql.startsWith("SELECT ")){
      return false;
    }

Aber wie ich das etwas aufziehen würde, habe ich ja bereits davor etwas geschrieben. Da wären das nicht eine große Menge an direkten String-Checks sondern mehrere Aufrufe. Das macht es dann aus meiner Sicht einfacher lesbar und man hat weniger doppelten Code.
 
Java:
if(!sql.startsWith("SELECT ")){
      return false;
    }

Aber wie ich das etwas aufziehen würde, habe ich ja bereits davor etwas geschrieben. Da wären das nicht eine große Menge an direkten String-Checks sondern mehrere Aufrufe. Das macht es dann aus meiner Sicht einfacher lesbar und man hat weniger doppelten Code.
Ich glaube, dazu reichen meine Kenntnisse lang nicht aus 🙁 Ich habe es jetzt umgedreht, sprich dass es 'false' zurückgibt, wenn kein 'SELECT' am Anfang steht usw.. Aber ich komme jetzt nicht weiter. Das ist wahrscheinlich komplett falsch, so wie ich es gemacht habe, oder?

Java:
public class SQLValidator {

  private static final char[] ALLOWED_CHARACTERS = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ', ',', '*'};

  private static final String[] ALLOWED_CHARACTERS_FOR_WHERE = {"<", ">", "=", "LIKE"};


  public boolean isValidSQL(String sql) {
    if(!sql.startsWith("SELECT ")){
      return false;
    }

    if(!sql.substring("SELECT ".length()).startsWith(ALLOWED_CHARACTERS.toString())) {
      return false;
    }

    if(!sql.substring(ALLOWED_CHARACTERS[].length()).startsWith("FROM ")){
      return false;
    }

    if(!sql.substring("FROM ".length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return false;
    }

    if(!sql.endsWith(";")){
      return false;
    }
    else if(!sql.substring(ALLOWED_CHARACTERS[].length()).startsWith("WHERE ")){
      return false;
    }

    if(!sql.substring("WHERE ".length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return false;
    }

    if(!sql.substring(ALLOWED_CHARACTERS[].length()).startsWith(ALLOWED_CHARACTERS_FOR_WHERE)){
      return false;
    }

    if(!sql.substring(ALLOWED_CHARACTERS_FOR_WHERE[].length()).startsWith(ALLOWED_CHARACTERS.toString())){
      return false;
    }

    if(!sql.endsWith(";")){
      return false;
    }

    return true;
  }
}
 
Ja, das ist so nicht korrekt.

Ich würde erst einmal eine Variable einfügen, die angibt, wie weit du derzeit bist...

Und dann musst Zeichen für Zeichen weiter gehen und prüfen, ob das aktuelle Zeichen in dem übergebenen Teil ist.

Ich glaube, dazu reichen meine Kenntnisse lang nicht aus
Du willst doch etwas dazu lernen. Methoden kannst Du erstellen und dann nutzen? Bei isValid scheint das ja auch zu gehen. Damit hast Du die Java Grundlagen für "Divide and Conquer" - Teile und Herrsche!

Also fangen wir doch einfach einmal damit an, was wir bisher so gesagt hatten:
int checkText(String testString, int currentPos, String serachString)

Das wäre dann jetzt (ganz auf die Schnelle geschrieben und noch nicht einmal getestet):
Java:
  /**
   * Gets the position after the String to check or -1 if checkString is not at given position.
   * @param originalValue String to look up.
   * @param position Position to start check at.
   * @param checkString Strign to look for.
   * @return new Position where checkString ended or -1 if it is not valid.
   */
  public static int getPositionAfterCheckString(final String originalValue, final int position, final String checkString) {
    // Validation missing!

    if (originalValue.substring(position).startsWith(checkString) {
      return position + checkString.length();
    }
    
    return -1;
  }

Das wäre dann ein Ansatz. Ist noch nicht wirklich objektorientiert. Wir nutzen nirgends "this", daher ist es static. Unschön. Findet man aber von Zeit zu Zeit als "Hilfsfunktionen" oder so ... das sind dann Utility-Klassen wie z.B. Arrays, Objects, .... Da wird etwas mit einer anderen Klasse gemacht, die man halt nicht erweitern / anpassen kann.

Damit wäre der Anfang bei Deiner Methode etwas wie:
Java:
  public static boolean isValidSQL(final String sql) {
    int position = 0;
    position = getPositionAfterCheckString(sql, position, "SELECT");
    if (position == -1) {
      return false;
    }

    // Here we have to continue ... check for one or more whitespace characters!
    
    return true;
  }

Dabei ist schon eine kleine Änderung wichtig: Das Leerzeichen ist weg bei SELECT! Whitespace ist nicht nur Leerzeichen sondern auch Tab und Return:
Java:
  /**
   * Whitespace characters
   */
  private static final char[] WHITESPACE_CHARACTERS = { ' ', '\t', '\r', '\n' };

Und nun kann man sich dazu eine Methode überlegen wie:
Java:
  public static int getPositionAfterCharacters(final String originalValue, final int position, final char[] characters, final Multiplicity multiplicity) {
    // Validation missing!

    switch (multiplicity) {
      case ONE:
      case NONE_OR_ONE:
        if (contains(characters, originalValue.charAt(position))) return position+1;
        if (multiplicity == Multiplicity.NONE_OR_MULTIPLE) return position;
        return -1;
        
      case NONE_OR_MULTIPLE:
      case ONE_OR_MULTIPLE:
        int newPosition = position;
        while (newPosition < originalValue.length() && contains(characters, originalValue.charAt(newPosition))) {
          newPosition++;
        }
        if (newPosition > position) return newPosition;
        if (multiplicity == Multiplicity.NONE_OR_MULTIPLE) return position;
        return -1;
        
      default:
        throw new IllegalStateException("Enum was enhanced without adding it inside this switch statement!");
    }
  }

Im ersten Block fehlt noch ein Check, ob position nicht schon am Ende ist. Am Ende wäre alles, was NONE* erlaubt, natürlich auch ok.
Aber das kannst Du gerne noch entsprechend anpassen. Ggf. willst Du die case Blöcke auch sauber trennen ... Das ist jetzt wirklich nur auf die Schnelle hin geschmiert ...

Und es braucht natürlich auch eine contains Methode:
Java:
  public static boolean contains(final char[] array, final char value) {
    for (char ch: array) {
      if (ch == value) return true;
    }
    return false;
  }

Aufruf wäre dann prinzipiell ähnlich wie schon bei dem ersten Check ...

Aber das nur um das Prinzip zu zeigen. Versuch einfach kleine und Kurze Methoden zu haben. Und evtl. ist das jetzt auch der ideale Augenblick, um die ersten Unit Tests zu schreiben um eben die Methoden, die wir gerade erzeugen, etwas zu testen.
 
Ja, das ist so nicht korrekt.

Ich würde erst einmal eine Variable einfügen, die angibt, wie weit du derzeit bist...

Und dann musst Zeichen für Zeichen weiter gehen und prüfen, ob das aktuelle Zeichen in dem übergebenen Teil ist.


Du willst doch etwas dazu lernen. Methoden kannst Du erstellen und dann nutzen? Bei isValid scheint das ja auch zu gehen. Damit hast Du die Java Grundlagen für "Divide and Conquer" - Teile und Herrsche!

Also fangen wir doch einfach einmal damit an, was wir bisher so gesagt hatten:


Das wäre dann jetzt (ganz auf die Schnelle geschrieben und noch nicht einmal getestet):
Java:
  /**
   * Gets the position after the String to check or -1 if checkString is not at given position.
   * @param originalValue String to look up.
   * @param position Position to start check at.
   * @param checkString Strign to look for.
   * @return new Position where checkString ended or -1 if it is not valid.
   */
  public static int getPositionAfterCheckString(final String originalValue, final int position, final String checkString) {
    // Validation missing!

    if (originalValue.substring(position).startsWith(checkString) {
      return position + checkString.length();
    }
   
    return -1;
  }

Das wäre dann ein Ansatz. Ist noch nicht wirklich objektorientiert. Wir nutzen nirgends "this", daher ist es static. Unschön. Findet man aber von Zeit zu Zeit als "Hilfsfunktionen" oder so ... das sind dann Utility-Klassen wie z.B. Arrays, Objects, .... Da wird etwas mit einer anderen Klasse gemacht, die man halt nicht erweitern / anpassen kann.

Damit wäre der Anfang bei Deiner Methode etwas wie:
Java:
  public static boolean isValidSQL(final String sql) {
    int position = 0;
    position = getPositionAfterCheckString(sql, position, "SELECT");
    if (position == -1) {
      return false;
    }

    // Here we have to continue ... check for one or more whitespace characters!
   
    return true;
  }

Dabei ist schon eine kleine Änderung wichtig: Das Leerzeichen ist weg bei SELECT! Whitespace ist nicht nur Leerzeichen sondern auch Tab und Return:
Java:
  /**
   * Whitespace characters
   */
  private static final char[] WHITESPACE_CHARACTERS = { ' ', '\t', '\r', '\n' };

Und nun kann man sich dazu eine Methode überlegen wie:
Java:
  public static int getPositionAfterCharacters(final String originalValue, final int position, final char[] characters, final Multiplicity multiplicity) {
    // Validation missing!

    switch (multiplicity) {
      case ONE:
      case NONE_OR_ONE:
        if (contains(characters, originalValue.charAt(position))) return position+1;
        if (multiplicity == Multiplicity.NONE_OR_MULTIPLE) return position;
        return -1;
       
      case NONE_OR_MULTIPLE:
      case ONE_OR_MULTIPLE:
        int newPosition = position;
        while (newPosition < originalValue.length() && contains(characters, originalValue.charAt(newPosition))) {
          newPosition++;
        }
        if (newPosition > position) return newPosition;
        if (multiplicity == Multiplicity.NONE_OR_MULTIPLE) return position;
        return -1;
       
      default:
        throw new IllegalStateException("Enum was enhanced without adding it inside this switch statement!");
    }
  }

Im ersten Block fehlt noch ein Check, ob position nicht schon am Ende ist. Am Ende wäre alles, was NONE* erlaubt, natürlich auch ok.
Aber das kannst Du gerne noch entsprechend anpassen. Ggf. willst Du die case Blöcke auch sauber trennen ... Das ist jetzt wirklich nur auf die Schnelle hin geschmiert ...

Und es braucht natürlich auch eine contains Methode:
Java:
  public static boolean contains(final char[] array, final char value) {
    for (char ch: array) {
      if (ch == value) return true;
    }
    return false;
  }

Aufruf wäre dann prinzipiell ähnlich wie schon bei dem ersten Check ...

Aber das nur um das Prinzip zu zeigen. Versuch einfach kleine und Kurze Methoden zu haben. Und evtl. ist das jetzt auch der ideale Augenblick, um die ersten Unit Tests zu schreiben um eben die Methoden, die wir gerade erzeugen, etwas zu testen.
Vielen Dank für die Hilfe, ich werde mich mal ran setzen!
 

Zurück
Oben