2010-10-07 54 views
9

Si estoy buscando una palabra en particular dentro de una cadena, por ejemplo, en la cadena "¿cómo estás?", Estoy buscando "son". ¿Un indexOf regular() trabajar más rápido y mejor, o un partido de expresiones regulares()Buscar una palabra en una cadena

String testStr = "how are you"; 
String lookUp = "are"; 

//METHOD1 
if (testStr.indexOf(lookUp) != -1) 
{ 
System.out.println("Found!"); 
} 

//OR 
//METHOD 2 
if (testStr.match(".*"+lookUp+".*")) 
{ 
System.out.println("Found!"); 
} 

¿Cuál de los dos métodos anteriores es una mejor manera de buscar una cadena dentro de otra cadena? ¿O hay una alternativa mucho mejor?

  • Ivard
+0

No es éste un duplicado exacto de esto: http://stackoverflow.com/q/3876246/450398 – Grodriguez

+0

En el j2se 1.6 el nuevo método es String.maches en lugar de http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#matches(java.lang.String) –

Respuesta

16

Si no le importa si es en realidad la palabra completa que estés a juego, a continuación, indexOf() será mucho más rápido.

Si, por el contrario, tiene que ser capaz de diferenciar entre are, harebrained, aren't etc., entonces necesita una expresión regular: \bare\b sólo igualará are como una palabra completa (\\bare\\b en Java).

\b es un delimitador de límite de palabras y coincide con el espacio vacío entre un carácter alfanumérico (letra, dígito o guión bajo) y un carácter no alfanumérico.

Advertencia: Esto también significa que si el término de búsqueda no es en realidad una palabra (digamos que usted está buscando ###), entonces estas anclas límite de la palabra sólo igualará en una cadena como aaa###zzz, pero no en +++###+++.

Advertencia adicional: Java tiene por defecto una cosmovisión limitada sobre lo que constituye un carácter alfanumérico. Solo las letras/dígitos ASCII (más el guión bajo) cuentan aquí, por lo que los delimitadores de límite de palabra fallarán en palabras como élève, relevé o ärgern. Read more about this (and how to solve this problem) here.

1

El método uno debe ser más rápido porque tiene una sobrecarga menor. si se trata de rendimiento en la búsqueda en archivos de gran tamaño, un método especializado como boyer moore pattern matching podría llevar a mejoras adicionales.

+0

Por lo tanto El motivo no se muestra el enlace http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm – stacker

+0

El guión en 'Boyer-M oore' fue realmente un en-dash ('U + 2013'). No sé de manera directa si eso es legal en una URL, pero a SO no parece gustarle. –

0

Si está buscando uno cadena dentro de otro que usted debe utilizar indexOf o contains método. Ejemplo: vea si "foo" está presente en una cadena.

Pero si buscas un patrón utiliza el método match.
Ejemplo: Vea si "foo" está presente en el principio/fin de la cadena. O vea si está presente como palabra completa.

El uso del método match para la búsqueda simple de cadenas no es eficiente debido a la sobrecarga del motor regex.

0

El primer método es más rápido y dado que no se trata de expresiones complejas, no hay ninguna razón para usar expresiones regulares aquí.

1

Si está buscando una cadena fija, no un patrón, como en el ejemplo de su pregunta, indexOf será mejor (más simple) y más rápido, ya que no necesita usar expresiones regulares.

Además, si la cadena que está buscando contiene caracteres que tienen un significado especial en expresiones regulares, con indexOf no tiene que preocuparse por escapar de estos caracteres.

En general, use indexOf donde sea posible, y match para coincidencia de patrones, donde indexOf no puede hacer lo que necesita.

0

por supuesto indexOf() es mejor que match(). one 'match()' se compone de muchas comparaciones: a == a, r == r, e == e; al mismo tiempo, anexar comodines que se dividen en muchos casos:?

  1. son
    ?? están
    ??? son
    ???? son
    ..... ... son? ¿¿son?? ¿¿¿son???

hasta que sea tan larga como las cuerdas originales.

0

Su pregunta prácticamente se responde a sí misma; si tiene que pregunte si la expresión regular es la mejor opción, es casi seguro que no lo es. Además, cuando elige entre soluciones regex y no regex, el rendimiento nunca debe ser su criterio principal. Espere hasta que tenga un código de trabajo y perfílgalo.

0

Un mejor enfoque para comparar ambas versiones es analizar el código fuente del método indexOf y los métodos regex.matches en sí, calcular el tiempo de ejecución de las implementaciones de algoritmo en Big_O_notation y comparar sus mejores, promedios y peores casos (charsequence found al comienzo, en el medio o al final de la cadena, respectivamente). El código fuente va aquí indexOf_source y aquí regex.matches. Necesitamos hacer un análisis en tiempo de ejecución de ambos para ver qué está haciendo exactamente. Tarea agitada pero es la única forma de hacer una verdadera comparación, el resto de ellos son solo suposiciones. Buena pregunta sin embargo.

0

lo uso:

public boolean searchStr(String search, String what) { 
    if(!search.replaceAll(what,"_").equals(search)) { 
     return true; 
    } 
    return false; 
} 

Ejemplo del uso:

String s = "abc"; 
String w = "bc"; 
if(searchStr(s,w)) { 
    //this returns true 
} 
s="qwe"; 
w="asd"; 
if(searchStr(s,w)) { 
    //this returns false 
} 
+1

Bienvenido en SO, aquí, es una buena práctica para explicar por qué usar su solución y no solo cómo. Eso hará que su respuesta sea más valiosa y ayudará al lector a tener una mejor comprensión de cómo lo hace. También sugiero que eche un vistazo a nuestras preguntas frecuentes: http://stackoverflow.com/faq. – ForceMagic

Cuestiones relacionadas