测试字符串是否包含字符串数组中的任何内容(kotlin)
Test if string contains anything from an array of strings (kotlin)
我是 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
}
作为开始(这忽略了 'match' 变量和匹配的关键字列表),我尝试根据我在 this question 找到的内容使用以下 if 语句,
if(Arrays.stream(keywords).parallel().anyMatch(content::contains))
但它在 "content" 下放了一条波浪线,并给了我这个错误
None of the following functions can be called with the arguments
supplied: public operator fun CharSequence.contains(char: Char,
ignoreCase: Boolean = ...): Boolean defined in kotlin.text public
operator fun CharSequence.contains(other: CharSequence, ignoreCase:
Boolean = ...): Boolean defined in kotlin.text @InlineOnly public
inline operator fun CharSequence.contains(regex: Regex): Boolean
defined in kotlin.text
您可以使用filter
函数只保留content
中包含的关键字:
val match = keywords.filter { it in content }
这里match
是一个List<String>
。如果你想在结果中得到一个数组,你可以添加.toTypedArray()
调用。
表达式 it in content
中的 in
运算符与 content.contains(it)
.
相同
如果要不区分大小写匹配,调用时需要指定ignoreCase
参数contains
:
val match = keywords.filter { content.contains(it, ignoreCase = true) }
另一个明显的选择是使用正则表达式进行不区分大小写的匹配:
arrayOf("foo", "bar", "spam").joinToString(prefix = "(?i)", separator = "|").toRegex())
将模式与前缀内联 (?i)
区分大小写的修饰符粘合在一起,并在关键字之间交替:(?i)foo|bar|spam
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"));
}
如果您要进行一些更复杂的匹配,例如,正则表达式方法可能会很方便。 non-/overlapping 匹配添加单词边界 \b
,等等
这是我没有使用 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"))
我是 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
}
作为开始(这忽略了 'match' 变量和匹配的关键字列表),我尝试根据我在 this question 找到的内容使用以下 if 语句,
if(Arrays.stream(keywords).parallel().anyMatch(content::contains))
但它在 "content" 下放了一条波浪线,并给了我这个错误
None of the following functions can be called with the arguments supplied: public operator fun CharSequence.contains(char: Char, ignoreCase: Boolean = ...): Boolean defined in kotlin.text public operator fun CharSequence.contains(other: CharSequence, ignoreCase: Boolean = ...): Boolean defined in kotlin.text @InlineOnly public inline operator fun CharSequence.contains(regex: Regex): Boolean defined in kotlin.text
您可以使用filter
函数只保留content
中包含的关键字:
val match = keywords.filter { it in content }
这里match
是一个List<String>
。如果你想在结果中得到一个数组,你可以添加.toTypedArray()
调用。
it in content
中的 in
运算符与 content.contains(it)
.
如果要不区分大小写匹配,调用时需要指定ignoreCase
参数contains
:
val match = keywords.filter { content.contains(it, ignoreCase = true) }
另一个明显的选择是使用正则表达式进行不区分大小写的匹配:
arrayOf("foo", "bar", "spam").joinToString(prefix = "(?i)", separator = "|").toRegex())
将模式与前缀内联 (?i)
区分大小写的修饰符粘合在一起,并在关键字之间交替:(?i)foo|bar|spam
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"));
}
如果您要进行一些更复杂的匹配,例如,正则表达式方法可能会很方便。 non-/overlapping 匹配添加单词边界 \b
,等等
这是我没有使用 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"))