Question

Je lis un fichier en utilisant BufferedReader, laisse dire que j'ai

line = br.readLine();

Je veux vérifier si cette ligne contient l'une des nombreuses chaînes possibles (que j'ai dans un tableau). Je voudrais pouvoir écrire quelque chose comme:

while (!line.matches(stringArray) { // not sure how to write this conditional
  do something here;
  br.readLine();
}

Je suis assez nouveau à la programmation et Java, je vais sur ce la bonne façon?

Était-ce utile?

La solution

Copier toutes les valeurs dans un Set<String> et utilisez contains():

Set<String> set = new HashSet<String> (Arrays.asList (stringArray));
while (!set.contains(line)) { ... }

[EDIT] Si vous voulez savoir si une partie de la ligne contient une chaîne de l'ensemble, il faut boucler sur l'ensemble. Remplacer set.contains(line) par un appel à:

public boolean matches(Set<String> set, String line) {
    for (String check: set) {
        if (line.contains(check)) return true;
    }
    return false;
}

Régler la vérification en conséquence lorsque vous utilisez ou regexp une méthode plus complexe pour la correspondance.

[EDIT2] Une troisième option consiste à concaténer les éléments du tableau dans une grande expression rationnelle avec |:

Pattern p = Pattern.compile("str1|str2|str3");

while (!p.matcher(line).find()) { // or matches for a whole-string match
    ...
}

Cela peut être plus pas cher si vous avez beaucoup d'éléments dans le tableau puisque le code regexp permettra d'optimiser le processus d'appariement.

Autres conseils

Cela dépend de ce stringArray est. Si c'est un Collection alors tout va bien. Si c'est un vrai tableau, vous devez faire un Collection. L'interface Collection a une méthode appelée contains() qui déterminera si un Object donné est dans le Collection.

Une façon simple de transformer un tableau en Collection:

String tokens[] = { ... }
List<String> list = Arrays.asList(tokens);

Le problème avec un List est que recherche est chère (techniquement linéaire ou O(n)). Un meilleur pari est d'utiliser un Set , qui est non ordonnée, mais a presque constante (O(1)) recherche. Vous pouvez construire un comme ceci:

D'un Collection:

Set<String> set = new HashSet<String>(stringList);

D'un tableau:

Set<String> set = new HashSet<String>(Arrays.asList(stringArray));

et set.contains(line) sera une opération pas cher.

Modifier Ok, je pense que votre question n'a pas été claire. Vous voulez voir si la ligne contient l'un des mots du tableau. Qu'est-ce que vous voulez alors quelque chose comme ceci:

BufferedReader in = null;
Set<String> words = ... // construct this as per above
try {
  in = ...
  while ((String line = in.readLine()) != null) {
    for (String word : words) {
      if (line.contains(word)) [
        // do whatever
      }
    }
  }
} catch (Exception e) {
  e.printStackTrace();
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
}

Ceci est tout à fait un chèque brut, qui est utilisé étonnamment ouvert et a tendance à donner des faux positifs gênants sur des mots comme « ferraille ». Pour une solution plus sophistiquée que vous avez probablement utiliser des expressions régulières et rechercher les limites de mots:

Pattern p = Pattern.compile("(?<=\\b)" + word + "(?=\b)");
Matcher m = p.matcher(line);
if (m.find() {
  // word found
}

Vous voudrez probablement faire plus efficacement (pas comme la compilation du modèle avec chaque ligne) mais c'est l'outil de base à utiliser.

En utilisant la fonction String.matches(regex), que sur la création d'une expression régulière qui correspond à l'une des chaînes dans le tableau de chaînes? Quelque chose comme

String regex = "*(";
for(int i; i < array.length-1; ++i)
  regex += array[i] + "|";
regex += array[array.length] + ")*";
while( line.matches(regex) )
{
  //. . . 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top