Kotlin проверить слова в строке - PullRequest
1 голос
/ 18 апреля 2019

У меня есть класс NSFW, который сканирует тексты, такие как имена и описания элементов, по списку известных слов NSFW.

Это был бы лучший подход для проверки списка строк, таких как

    let nsfw = listof(
    "badword",
    "curseword",
    "ass",
    ... 200+ more
    )

против строки типа:

This is the text that contains a badword // returns true

Обратите внимание, что мне нужно проверить на наличие полных слов.не части слов.

поэтому предложение:

The grass is grean // returns false

Потому что трава не плохое слово.

Я пробовал что-то подобное, но оно не проверяет полные слова.

        val result =  nsfw.filter { it in sentence.toLowerCase() }

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Вы можете построить регулярное выражение, как

\b(?:word1|word2|word3...)\b

См. демо регулярных выражений . Затем используйте его с методом Regex.containsMatchIn :

val nsfw = listOf(
    "badword",
    "curseword",
    "ass"
)
val s1 = "This is the text that contains a badword"
val s2 = "The grass is grean"
val rx = Regex("\\b(?:${nsfw.joinToString(separator="|")})\\b")
println(rx.containsMatchIn(s1)) // => true
println(rx.containsMatchIn(s2)) // => false

См. это демо Kotlin .

Здесь nsfw.joinToString(separator="|") соединяет слова с помощью конвейера (оператор чередования), а "\\b(?:${nsfw.joinToString(separator="|")})\\b" создает правильное регулярное выражение.

Если ваши слова могут содержать специальные метасимволы регулярных выражений, такие как +, ?, (, ) и т. Д., Вам необходимо "предварительно обработать" значения nsfw с помощью Regex.escape метод :

val rx = Regex("\\b(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})\\b")
                            ^^^^^^^^^^^^^^^^^^^^^^     

См. Демоверсия Kotlin .

И еще одна вещь: если ключевые слова могут начинаться / заканчиваться символами, отличными от букв, цифр и подчеркиваний, вы не можете полагаться на \b границы слов. Вы можете

  • Использовать границы пробелов: val rx = Regex("(?<!\\S)(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})(?!\\S)")
  • Используйте однозначные границы слов: val rx = Regex("(?<!\\w)(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})(?!\\w)")
0 голосов
/ 18 апреля 2019

Вы можете использовать split() в строке, которую вы хотите проверить, с пробелом в качестве разделителя, так что вы создаете список его слов, хотя это не всегда гарантирует, что все слова будутизвлечено успешно, поскольку могут существовать другие разделители слов, такие как точки или запятые и т. д. Если это вас устраивает, сделайте следующее:

val nsfw = listOf(
    "badword",
    "curseword",
    "ass"
)

val str = "This is the text that contains a badword"
val words = str.toLowerCase().split("\\s+".toRegex())
val containsBadWords = words.firstOrNull { it in nsfw } != null
println(containsBadWords)

выведет

true

Если вы хотите список "плохие слова" :

val badWords = words.filter { it in nsfw }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...