Java / Kotlin:标记字符串,忽略嵌套引号的内容

时间:2019-02-04 19:26:35

标签: java string kotlin tokenize

我想通过空格分隔字符,但将空格保留在引号(以及引号本身)内。问题是,引号可以嵌套,对于单引号和双引号,我也需要这样做。因此,我想从this "'"is a possible option"'" and ""so is this"" and '''this one too''' and even ""mismatched quotes"行中获得[this, "'"is a possible option"'", and, ""so is this"", and, '''this one too''', and, even, ""mismatched quotes"]

已经问过这个问题,但不是我要问的确切问题。 Here有几种解决方案:一种使用匹配器(在这种情况下,"""x"""将被拆分为[""", x"""],所以这不是我所需要的)和Apache Commons(可与{{1 }},但不能使用"""x""",因为它会使用前两个双引号并将""x""留在最后两个双引号)。也有人建议手动编写一个函数,但这是最后的选择。

1 个答案:

答案 0 :(得分:1)

您可以使用以下正则表达式来实现:["']+[^"']+?["']+。使用该模式,您可以像这样检索要拆分的索引:

val indices = Regex(pattern).findAll(this).map{ listOf(it.range.start, it.range.endInclusive) }.flatten().toMutableList()

剩下的就是用子字符串建立列表。这里是完整的功能:

fun String.splitByPattern(pattern: String): List<String> {

    val indices = Regex(pattern).findAll(this).map{ listOf(it.range.start, it.range.endInclusive) }.flatten().toMutableList()

    var lastIndex = 0
    return indices.mapIndexed { i, ele ->

        val end = if(i % 2 == 0) ele else ele + 1 // magic

        substring(lastIndex, end).apply {
            lastIndex = end
        }
    }
}

用法:

val str = """
this "'"is a possible option"'" and ""so is this"" and '''this one too''' and even ""mismatched quotes"
""".trim()

println(str.splitByPattern("""["']+[^"']+?["']+"""))

输出:

  

[this,“'”是一个可能的选择“'”,and,“”这也是“,and,''this too''',甚至是”“不匹配的引号”]

Kotlin's playground上尝试一下!