测试字符串是否包含字符串数组中的任何内容(kotlin)

时间:2018-06-10 23:14:06

标签: arrays string kotlin contains

我是Kotlin的新手(我有Java背景),我似乎无法弄清楚如何检查字符串是否包含关键字列表中的匹配项。

我想要做的是检查一个字符串是否包含一系列关键字匹配(不区分大小写)。如果是,请打印出匹配的关键字和包含该关键字的字符串。 (我将循环遍历文件中的一串字符串。)

以下是初学者的MVE:

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
}

作为一个开始(这会忽略'匹配'变量并获得匹配关键字列表),我尝试使用以下if语句根据我在this question找到的内容,

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

但是它在“内容”下面放了一条波浪线并给了我这个错误

  

使用参数不能调用以下任何函数   提供:公共运营商乐趣CharSequence.contains(char:Char,   ignoreCase:Boolean = ...):在kotlin.text public中定义的布尔值   运营商乐趣CharSequence.contains(其他:CharSequence,ignoreCase:   Boolean = ...):在kotlin.text @InlineOnly public中定义的布尔值   内联运算符有趣CharSequence.contains(正则表达式:正则表达式):布尔值   在kotlin.text中定义

3 个答案:

答案 0 :(得分:7)

您可以使用filter功能仅保留content中包含的关键字:

val match = keywords.filter { it in content }

此处matchList<String>。如果要在结果中获取数组,可以添加.toTypedArray()调用。

表达式in中的

it in content运算符与content.contains(it)相同。

如果您希望不区分大小写匹配,则需要在调用ignoreCase时指定contains参数:

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

答案 1 :(得分:2)

另一个明显的选择是使用正则表达式进行不区分大小写的匹配:

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

将带有前缀内联(?i) incase-sensitive修饰符的模式粘合在一起,并在关键字之间进行替换:(?i)foo|bar|spam

Sample 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"));
}

如果您正在进行一些更复杂的匹配,例如正则表达式方法可能会很方便。非重叠匹配添加单词边界\b

答案 2 :(得分:0)

这是我不使用Streams的方法:

fun String.containsAnyOfIgnoreCase(keywords: List<String>): Boolean {
    for (keyword in keywords) {
        if (this.contains(keyword, true)) return true
    }
    return false
}

用法:

"test string".containsAnyOfIgnoreCase(listOf("abc","test"))