texto - Cómo encontrar una palabra completa en una cadena en Java
como buscar una palabra en un archivo de texto en java (13)
Tengo una cadena que tengo que analizar para diferentes palabras clave. Por ejemplo, tengo el String:
"Vendré a encontrarte a los 123woods"
Y mis palabras clave son
''123woods'' ''maderas''
Debería informar siempre que tenga un partido y dónde. Múltiples ocurrencias también deben ser contabilizadas. Sin embargo, para este, debería conseguir un partido solo en 123woods, no en bosques. Esto elimina el uso del método String.contains (). Además, debería poder tener una lista / conjunto de palabras clave y verificar al mismo tiempo su ocurrencia. En este ejemplo, si tengo ''123woods'' y ''come'', debería obtener dos apariciones. La ejecución del método debe ser algo rápida en textos grandes.
Mi idea es usar StringTokenizer, pero no estoy seguro si funcionará bien. ¿Alguna sugerencia?
¿Qué tal algo como Arrays.asList(String.split(" ")).contains("xx")
?
Consulte String.split() y ¿Cómo puedo probar si una matriz contiene un cierto valor ?
El siguiente ejemplo se basa en sus comentarios. Utiliza una lista de palabras clave, que se buscará en una cadena determinada utilizando límites de palabras. Utiliza StringUtils de Apache Commons Lang para construir la expresión regular e imprimir los grupos coincidentes.
String text = "I will come and meet you at the woods 123woods and all the woods";
List<String> tokens = new ArrayList<String>();
tokens.add("123woods");
tokens.add("woods");
String patternString = "//b(" + StringUtils.join(tokens, "|") + ")//b";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
Si busca más rendimiento, puede echar un vistazo a StringSearch : algoritmos de coincidencia de patrones de alto rendimiento en Java.
Espero que esto funcione para usted:
String string = "I will come and meet you at the 123woods";
String keyword = "123woods";
Boolean found = Arrays.asList(string.split(" ")).contains(keyword);
if(found){
System.out.println("Keyword matched the string");
}
Intenta emparejar usando expresiones regulares. Coincide con "/ b123wood / b", / b es un salto de palabra.
La solución parece ser aceptada durante mucho tiempo, pero la solución podría mejorarse, por lo que si alguien tiene un problema similar:
Esta es una aplicación clásica para algoritmos de búsqueda de patrones múltiples.
Java Pattern Search (con Matcher.find
) no está calificado para hacer eso. La búsqueda de exactamente una palabra clave está optimizada en Java, la búsqueda de una expresión-o utiliza el autómata no determinista regex, que está retrocediendo en desajustes. En el peor de los casos, cada carácter del texto se procesará l veces (donde l es la suma de las longitudes del patrón).
La búsqueda de patrón único es mejor, pero no calificada también. Uno tendrá que comenzar la búsqueda completa de cada patrón de palabra clave. En el peor de los casos, cada carácter del texto se procesará p veces, donde p es el número de patrones.
La búsqueda de patrones múltiples procesará cada carácter del texto exactamente una vez. Los algoritmos adecuados para dicha búsqueda serían Aho-Corasick, Wu-Manber o Set Backwards Oracle Matching. Estos se pueden encontrar en bibliotecas como Stringsearchalgorithms o byteseek .
// example with StringSearchAlgorithms
AhoCorasick stringSearch = new AhoCorasick(asList("123woods", "woods"));
CharProvider text = new StringCharProvider("I will come and meet you at the woods 123woods and all the woods", 0);
StringFinder finder = stringSearch.createFinder(text);
List<StringMatch> all = finder.findAll();
Mirando hacia atrás a la pregunta original, necesitamos encontrar algunas palabras clave en una oración dada, contar el número de ocurrencias y saber algo sobre dónde. No entiendo muy bien qué significa "dónde" (¿es un índice en la oración?), Así que pasaré ese ... Todavía estoy aprendiendo Java, un paso a la vez, así que veré a ese a su debido tiempo :-)
Debe tenerse en cuenta que las oraciones comunes (como la de la pregunta original) pueden tener palabras clave repetidas, por lo tanto, la búsqueda no puede simplemente preguntar si una palabra clave determinada "existe o no" y contarla como 1 si existe. Puede haber más de uno de lo mismo. Por ejemplo:
// Base sentence (added punctuation, to make it more interesting):
String sentence = "Say that 123 of us will come by and meet you, "
+ "say, at the woods of 123woods.";
// Split it (punctuation taken in consideration, as well):
java.util.List<String> strings =
java.util.Arrays.asList(sentence.split(" |,|//."));
// My keywords:
java.util.ArrayList<String> keywords = new java.util.ArrayList<>();
keywords.add("123woods");
keywords.add("come");
keywords.add("you");
keywords.add("say");
Al observarlo, el resultado esperado sería 5 para "Say" + "come" + "you" + "say" + "123woods", contando "say" dos veces si vamos en minúscula. Si no lo hacemos, entonces el conteo debe ser 4, "Say" es excluido y "say" incluido. Multa. Mi sugerencia es:
// Set... ready...?
int counter = 0;
// Go!
for(String s : strings)
{
// Asking if the sentence exists in the keywords, not the other
// around, to find repeated keywords in the sentence.
Boolean found = keywords.contains(s.toLowerCase());
if(found)
{
counter ++;
System.out.println("Found: " + s);
}
}
// Statistics:
if (counter > 0)
{
System.out.println("In sentence: " + sentence + "/n"
+ "Count: " + counter);
}
Y los resultados son:
Encontrado: Say
Encontrado: venido
Te encontré
Encontrado: decir
Encontrado: 123woods
En una frase: di que 123 de nosotros vendremos y te encontraremos, digamos, en el bosque de 123woods.
Cuenta: 5
Obtuve una forma de unir la palabra exacta de String en Android:
String full = "Hello World. How are you ?";
String one = "Hell";
String two = "Hello";
String three = "are";
String four = "ar";
boolean is1 = isContainExactWord(full, one);
boolean is2 = isContainExactWord(full, two);
boolean is3 = isContainExactWord(full, three);
boolean is4 = isContainExactWord(full, four);
Log.i("Contains Result", is1+"-"+is2+"-"+is3+"-"+is4);
Result: false-true-true-false
Función para la palabra coincidente:
private boolean isContainExactWord(String fullString, String partWord){
String pattern = "//b"+partWord+"//b";
Pattern p=Pattern.compile(pattern);
Matcher m=p.matcher(fullString);
return m.find();
}
Hecho
Para que coincida con "123woods" en lugar de "maderas", use la agrupación atómica en la expresión regular. Una cosa que debe tenerse en cuenta es que, en una cadena para que coincida con "123woods" solo, coincidirá con el primer "123woods" y se cierra en lugar de buscar la misma cadena más.
/b(?>123woods|woods)/b
busca 123woods como búsqueda principal, una vez que se empareja, sale de la búsqueda.
Puedes usar expresiones regulares. Use los métodos de Matcher y Pattern para obtener el resultado deseado
También puede usar la coincidencia de expresiones regulares con el indicador / b (límite de palabra completa).
Una forma mucho más simple de hacer esto es usar split ():
String match = "123woods";
String text = "I will come and meet you at the 123woods";
String[] sentence = text.split();
for(String word: sentence)
{
if(word.equals(match))
return true;
}
return false;
Esta es una forma más simple y menos elegante de hacer lo mismo sin usar tokens, etc.
Use los límites de palabras Regex + como otros respondieron.
"I will come and meet you at the 123woods".matches(".*//b123woods//b.*");
será cierto
"I will come and meet you at the 123woods".matches(".*//bwoods//b.*");
será falso
public class FindTextInLine {
String match = "123woods";
String text = "I will come and meet you at the 123woods";
public void findText () {
if (text.contains(match)) {
System.out.println("Keyword matched the string" );
}
}
}