Pregunta

Estoy leyendo un archivo usando BufferedReader, lo que permite decir que tengo

line = br.readLine();

Quiero comprobar si esta línea contiene una de las muchas posibles cadenas (que no tengo en una matriz). Me gustaría ser capaz de escribir algo como:

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

Soy bastante nuevo en la programación y Java, voy de este por el camino correcto?

¿Fue útil?

Solución

Copiar todos los valores en un Set<String> y luego usar contains():

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

[EDIT] Si desea averiguar si una parte de la línea contiene una cadena a partir del conjunto, tiene que bucle sobre el conjunto. Reemplazar set.contains(line) con una llamada a:

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

Ajustar el cheque en consecuencia cuando se utiliza expresiones regulares o un método más complejo para la coincidencia.

[Edit2] Una tercera opción es para concatenar los elementos de la matriz en una enorme expresión regular con |:

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

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

Esto puede ser más barato si tiene muchos elementos de la matriz ya que el código de expresión regular optimizar el proceso de correspondencia.

Otros consejos

Depende de lo que es stringArray. Si se trata de un Collection entonces está bien. Si se trata de una verdadera matriz, debe hacerlo un Collection. La interfaz Collection tiene un método llamado contains() que determinará si un Object dado está en el Collection.

Una manera sencilla de convertir un array en un Collection:

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

El problema con un List es que las operaciones de búsqueda es caro (técnicamente lineal o O(n)). Una apuesta mejor es usar un Set, que es desordenada, pero tiene casi constante de consulta (O(1)). Es posible construir una como esta:

Desde un Collection:

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

Desde una matriz:

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

y luego set.contains(line) habrá una operación barata.

Editar Ok, creo que su pregunta no era clara. ¿Quieres ver si la línea contiene alguna de las palabras de la matriz. Lo que quieres, entonces es algo como esto:

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) { } }
}

Este es un cheque bastante crudo, que se utiliza sorprendentemente abierto y tiende a dar falsos positivos molestos en palabras como "chatarra". Para una solución más sofisticada es probable que tenga que utilizar una expresión regular y buscar los límites de palabra:

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

Es probable que desee hacer esto de manera más eficiente (como no compilar el patrón con cada línea) pero esa es la herramienta básica para su uso.

Uso de la función String.matches(regex), ¿qué pasa con la creación de una expresión regular que coincide con una cualquiera de las cadenas de la matriz de cadenas? Algo así como

String regex = "*(";
for(int i; i < array.length-1; ++i)
  regex += array[i] + "|";
regex += array[array.length] + ")*";
while( line.matches(regex) )
{
  //. . . 
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top