TL; DR Para subcadenas simples es mejor, pero para solo las palabras completas de Expresión regular son probablemente mejores.
La mejor manera de ver qué método es más eficaz es probarlo.
Puede usar String.contains()
en lugar de String.indexOf()
para simplificar su código no regexp.
Para buscar diferentes palabras con la expresión regular se ve así:
apple|orange|pear|banana|kiwi
Los |
trabajos como OR
en las expresiones regulares.
Mi muy simple código de prueba es el siguiente:
public class TestContains {
private static String containsWord(Set<String> words,String sentence) {
for (String word : words) {
if (sentence.contains(word)) {
return word;
}
}
return null;
}
private static String matchesPattern(Pattern p,String sentence) {
Matcher m = p.matcher(sentence);
if (m.find()) {
return m.group();
}
return null;
}
public static void main(String[] args) {
Set<String> words = new HashSet<String>();
words.add("apple");
words.add("orange");
words.add("pear");
words.add("banana");
words.add("kiwi");
Pattern p = Pattern.compile("apple|orange|pear|banana|kiwi");
String noMatch = "The quick brown fox jumps over the lazy dog.";
String startMatch = "An apple is nice";
String endMatch = "This is a longer sentence with the match for our fruit at the end: kiwi";
long start = System.currentTimeMillis();
int iterations = 10000000;
for (int i = 0; i < iterations; i++) {
containsWord(words, noMatch);
containsWord(words, startMatch);
containsWord(words, endMatch);
}
System.out.println("Contains took " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
matchesPattern(p,noMatch);
matchesPattern(p,startMatch);
matchesPattern(p,endMatch);
}
System.out.println("Regular Expression took " + (System.currentTimeMillis() - start) + "ms");
}
}
Los resultados que obtuve fueron los siguientes:
Contains took 5962ms
Regular Expression took 63475ms
Obviamente los tiempos pueden variar en función del número de palabras que se buscaron y la Las cadenas que se buscan, pero parece ser ~ 10 veces más rápido que las expresiones regulares para una búsqueda simple como esta.
Al usar Expresiones regulares para buscar Cuerdas dentro de otra Cadena, está utilizando una maza para romper una nuez, así que supongo que no debería sorprendernos que sea más lenta. Guarde expresiones regulares para cuando los patrones que desea encontrar son más complejos.
Un caso en el que es posible que desee utilizar expresiones regulares es si indexOf()
y no va a hacer el trabajo porque solo deseas para que coincida con las palabras enteras y no sólo subseries, por ejemplo Quiere hacer coincidir pear
pero no spears
. Las expresiones regulares manejan bien este caso ya que tienen el concepto de word boundaries.
En este caso nos gustaría cambiar nuestro patrón a:
\b(apple|orange|pear|banana|kiwi)\b
El \b
dice que sólo se corresponde con el principio o el final de una palabra y el grupo entre paréntesis el o expresiones juntos.
Nota, al definir este patrón en su código que necesita para escapar de las barras invertidas con otra barra invertida:
Pattern p = Pattern.compile("\\b(apple|orange|pear|banana|kiwi)\\b");
¿No puedes leer? Nunca dije que fuera eficiente. –
El rendimiento depende de la longitud de la expresión regular. Si tiene menos de 1000 caracteres, continúe. Si es más tiempo, necesitas otra solución. Por ejemplo, divida el texto para separar las palabras y compruébelas con la tabla hash predefinida/conjunto de palabras "conocidas". – AlexR
@deporter el propósito de la respuesta es dar una buena pista sobre cómo resolver la pregunta para no proporcionar una solución perfecta, brillante y de clase mundial. Se puede mejorar fácilmente y, en cuanto a legibilidad, si tiene 200 cadenas (una razón más para no usar regexp para eso), puede usar un for-loop y concatenar en un 'StringBuilder'. Creo que mi respuesta proporciona suficiente sabor. –