2008-11-20 37 views
13
ArrayList <String> list = new ArrayList(); 
list.add("behold"); 
list.add("bend"); 
list.add("bet"); 
list.add("bear"); 
list.add("beat"); 
list.add("become"); 
list.add("begin"); 

Hay una manera de buscar la expresión regular bea. * Y obtener los índices como en ArrayList.indexOf?Buscar una expresión regular en una lista de arrays java

EDIT: devolución de los artículos está bien, pero necesito algo con más rendimiento que una búsqueda lineal

+0

No se puede mejorar el rendimiento si pon tus cuerdas en una lista. ¿Tu expresión regular siempre es un prefijo, o quieres manejar alguna expresión regular? – erickson

+0

Entonces, ¿qué estructura de datos debo usar? Mi expresión regular siempre es un prefijo. – kmilo

+0

Recomiendo cierta estructura de datos de autómatas. https://en.wikipedia.org/wiki/Trie –

Respuesta

1

No creo que hay una manera de Java API de hacer esto, ni tampoco hay una forma de Apache Commons de hacer esto . Sin embargo, no sería difícil hacer tu propio.

7

¿Hay un método incorporado? No que yo sepa. Sin embargo, debería ser bastante fácil hacerlo usted mismo. Aquí hay un código, no está comprobado que debe darle la idea básica:

import java.util.regex.Pattern; 
import java.util.ListIterator; 
import java.util.ArrayList; 

/** 
* Finds the index of all entries in the list that matches the regex 
* @param list The list of strings to check 
* @param regex The regular expression to use 
* @return list containing the indexes of all matching entries 
*/ 
List<int> getMatchingIndexes(List<String> list, String regex) { 
    ListIterator<String> li = list.listIterator(); 

    List<int> indexes = new ArrayList<int>(); 

    while(li.hasNext()) { 
    int i = li.nextIndex(); 
    String next = li.next(); 
    if(Pattern.matches(regex, next)) { 
     indexes.add(i); 
    } 
    } 

    return indexes 
} 

que podría tener el uso de patrones y ListIterator partes un poco mal (nunca he utilizado tampoco), pero que debe dar la idea básica. También podría hacer un bucle simple for en lugar del bucle while sobre el iterador.

+0

Personalmente, creo que los métodos de API deben tomar argumentos y devolver valores del tipo más abstracto posible. Por lo tanto, mi corrección pedante de su respuesta sería: public List getMatchingIndices (Lista list, String regex) {..} – user38051

+0

Buen punto. Estaba lanzándolo muy rápido y no presté tanta atención a esas cosas. – Herms

+0

FYI, no es un parámetro de tipo válido. Tendría que hacer una lista . Además, cuando usa una expresión regular en un bucle como este, debe compilarlo en un objeto Pattern antes de ingresar al bucle, como lo hizo DJClayworth. –

4

Una opción es usar Apache Commons CollectionUtils método "seleccionar". Debería crear un objeto Predicado (un objeto con un único método de "evaluación" que utiliza la expresión regular para verificar una coincidencia y devolver verdadero o falso) y luego puede buscar elementos en la lista que coincida. Sin embargo, no devolverá los índices, devolverá una colección que contenga los elementos.

15

Herms tiene los fundamentos correctos. Si desea que las cadenas y no los índices entonces usted puede mejorar mediante el uso de Java 5 foreach bucle:

import java.util.regex.Pattern; 
import java.util.ListIterator; 
import java.util.ArrayList; 

/** 
* Finds the index of all entries in the list that matches the regex 
* @param list The list of strings to check 
* @param regex The regular expression to use 
* @return list containing the indexes of all matching entries 
*/ 
List<String> getMatchingStrings(List<String> list, String regex) { 

    ArrayList<String> matches = new ArrayList<String>(); 

    Pattern p = Pattern.compile(regex); 

    for (String s:list) { 
    if (p.matcher(s).matches()) { 
     matches.add(s); 
    } 
    } 

    return matches 
} 
+1

Pensé en devolver las cadenas de coincidencia reales, pero la pregunta específicamente preguntó por las indicies. Sin embargo, devolver las cadenas correspondientes es en general un poco más limpio. – Herms

3

Se trata de un un trazador de líneas de la guayaba:

final Iterable<String> matches = Iterables.filter(myStrings, Predicates.contains(Pattern.compile("myPattern"))); 

for (final String matched : matches) { 
    ... 
} 
Cuestiones relacionadas