web-dev-qa-db-fra.com

Teste si la chaîne contient quelque chose d'un tableau de chaînes (kotlin)

Je suis nouveau sur Kotlin (j'ai un Java background) et je n'arrive pas à comprendre comment vérifier si une chaîne contient une correspondance à partir d'une liste de mots clés.

Ce que je veux faire est de vérifier si une chaîne contient une correspondance à partir d'un tableau de mots clés (insensible à la casse s'il vous plaît) . Si tel est le cas, imprimez le (s) mot (s) -clé (s) correspondant (s) et la chaîne contenant le mot-clé. (Je vais boucler sur un tas de chaînes dans un fichier).

Voici un MVE pour commencer:

val keywords = arrayOf("foo", "bar", "spam")

fun search(content: String) {
    var match = <return an array of the keywords that content contained>
    if(match.size > 0) {
          println("Found match(es): " + match + "\n" + content)
    }
}   

fun main(args: Array<String>) {
    var str = "I found food in the barn"
    search(str) //should print out that foo and bar were a match
}

Pour commencer (cela ignore la variable "match" et l'obtention d'une liste de mots-clés correspondant), j'ai essayé d'utiliser l'instruction if suivante en fonction de ce que j'ai trouvé à cette question ,

if(Arrays.stream(keywords).parallel().anyMatch(content::contains))

mais il a mis une ligne ondulée sous "contenu" et m'a donné cette erreur

Aucune des fonctions suivantes ne peut être appelée avec les arguments fournis: opérateur public fun CharSequence.contains (char: Char, ignoreCase: Boolean = ...): booléen défini dans kotlin.text public operator fun CharSequence.contains (autre: CharSequence, ignoreCase: Boolean = ...): Boolean défini dans kotlin.text @InlineOnly public inline operator fun CharSequence.contains (regex: Regex): Boolean défini dans kotlin.text

12
takanuva15

Vous pouvez utiliser la fonction filter pour ne laisser que les mots clés contenus dans content:

val match = keywords.filter { it in content }

Ici match est un List<String>. Si vous souhaitez obtenir un tableau dans le résultat, vous pouvez ajouter .toTypedArray() call.

L'opérateur in dans l'expression it in content est le même que content.contains(it).

Si vous voulez avoir une correspondance insensible à la casse, vous devez spécifier le paramètre ignoreCase lors de l'appel de contains:

val match = keywords.filter { content.contains(it, ignoreCase = true) }
12
Ilya

Un autre choix évident consiste à utiliser une expression régulière faisant une correspondance insensible à la casse:

arrayOf("foo", "bar", "spam").joinToString(prefix = "(?i)", separator = "|").toRegex())

Colle un motif avec un préfixe en ligne (?i) modificateur sensible à la casse et alternances entre les mots clés: (?i)foo|bar|spam

Exemple de code :

private val keywords = arrayOf("foo", "bar", "spam")
private val pattern = keywords.joinToString(prefix = "(?i)", separator = "|")
private val rx = pattern.toRegex()

fun findKeyword(content: String): ArrayList<String> { 
    var result = ArrayList<String>()
    rx.findAll(content).forEach { result.add(it.value) }
    return result
}

fun main(args: Array<String>) { 
    println(findKeyword("Some spam and a lot of bar"));
}

L'approche regex pourrait être pratique si vous recherchez une correspondance plus complexe, par exemple correspondances non/superposées ajout de limites de mot \b, etc.

3
wp78de