2

我正在使用 Javalin & Exposed ORM 构建一个小型 API。我正在尝试使用正则表达式 where 条件但抛出异常,因为由于我的代码执行的 SQL 查询似乎不完整(模式丢失)。

fun getUsersByFilter(filter: String): List<User> {
    val regex = StringBuilder("/")
            .append(filter.toLowerCase())
            .append("/i")
            .toString()


    /**
     * The .regexp(someString) method take a string as argument (a pattern)
     */
    val users = transaction {
        User.find{ Users.pseudo.regexp(regex)  }.toList()
    }

    return users
}
  Position : 141. Statement(s): SELECT users.id, users.pseudo, users.email, users."password", users.admin, users.created_at, users.updated_at FROM users WHERE users.pseudo REGEXP ?
org.jetbrains.exposed.exceptions.ExposedSQLException: org.postgresql.util.PSQLException: ERREUR: erreur de syntaxe sur ou près de « REGEXP »
  Position : 141
SQL: [SELECT users.id, users.pseudo, users.email, users."password", users.admin, users.created_at, users.updated_at FROM users WHERE users.pseudo REGEXP ?]

有人能帮助我吗?

4

2 回答 2

1

好的我明白了。即使在使用 StringBuilder 时,正则表达式参数也已正确传递给查询(异常消息中的问号只是指向参数...)。该错误来自 PostgreSQL,因为 PostgreSQL 中根本不存在“REGEXP”函数......

我终于使用了这段代码:

    fun getUsersByFilter(filter: String): List<User> {
        val regex = "%${filter.toLowerCase()}%"

        val users = transaction {
            User.find{ Users.pseudo.lowerCase().like(regex) }.toList()
        }

        return users
    }
于 2019-06-10T13:12:51.203 回答
0

从您的代码看来,您似乎试图通过连接/、模式和/i分隔符 + 不区分大小写的标志从用户输入创建正则表达式。

这是错误的,因为:

  • 在 Kotlin(和 Java)中,正则表达式模式是通过字符串字面量指定的,而不是像 JavaScript、PHP、Perl 中通常那样的正则表达式字面量,因此您不需要/在两端都添加
  • 使用特定选项( )设置不区分大小写RegexOptions.IGNORE_CASE,或者更简单地使用内联修饰符,如(?i). 在开头添加它,整个正则表达式将不区分大小写。
  • 但是,应该按字面意思匹配的用户部分如果包含特殊的正则表达式元字符,则会引发异常。你需要“引用”它,在 Kotlin 中,你有Regex.fromLiteral方法

所以,我建议使用

val regex = "(?i)" + Regex.fromLiteral(filter)
于 2019-06-07T17:49:30.950 回答