Java 如何拆分多维数组字符串

Java 如何拆分多维数组字符串,java,arrays,regex,multidimensional-array,kotlin,Java,Arrays,Regex,Multidimensional Array,Kotlin,如何从数组的字符串中拆分和检索数据 对象有一个可以是多维的变量数组 演示输入字符串 CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true] 预期结果 CONTAINER 1 "one" false [CONTAINER [2, "two", false]] 42 true 然后,我将采取第5组,并再次运行它,以获得其余的对象 拆分字符串以获取内部数据的好方法是什么 可以使用正则表达式吗 如果另一种布局更容易,我

如何从数组的字符串中拆分和检索数据

对象有一个可以是多维的变量数组

演示输入字符串

CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]
预期结果

CONTAINER
1
"one"
false
[CONTAINER [2, "two", false]]
42
true
然后,我将采取第5组,并再次运行它,以获得其余的对象

拆分字符串以获取内部数据的好方法是什么

可以使用正则表达式吗


如果另一种布局更容易,我可以选择以不同的方式格式化字符串。

最简单的方法是使用拆分:

val input = """CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""

input.split(" ", "[", ",", "]").filter {
    it != ""
}.forEach {
    println(it)
}
输出:

CONTAINER
1
"one"
false
CONTAINER
2
"two"
false
42
true

由于可以手动识别根容器中的数组,因此我可以用普通方括号替换方括号,以便于检索数据

input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")

        val arraySplit = input.split("(", ")")
从那里可以使用正则表达式模式来迭代嵌套,以检索和替换所有后续容器

private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")
没有我想要的那么干净,但它很实用。主要关注点是支持多个嵌套层,例如在本例中:

输入

输出

CONTAINER [1, "one", false, [$array], 42, true]
$array = $4, $2, $3
$0 = CONTAINER [3, "three"]
$1 = CONTAINER [false]
$2 = CONTAINER [2, "string", false]
$3 = CONTAINER [4]
$4 = CONTAINER [2, "two", $0, $1, true]
例如,感谢@Alexey Soshin

全班:

import org.junit.Assert
import org.junit.Test
import java.util.regex.Pattern

class ContainerTest {

    private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")

    /**
     * Checks if string contains a full array in the middle or at the end of the container values
     * @return whether a verified container contains an array
     */
    private fun hasArray(string: String): Boolean {
        return string.contains(", [") && (string.contains("]], ") || string.endsWith("]]]"))
    }

    /**
     * Replaces last occurrence of a substring
     * Credit: https://stackoverflow.com/a/16665524/2871826
     */
    private fun replaceLast(string: String, substring: String, replacement: String): String {
        val index = string.lastIndexOf(substring)
        return if (index == -1) string else string.substring(0, index) + replacement + string.substring(index + substring.length)
    }

    /**
     * Splits root container and returns string contents of it's array
     */
    private fun extractArray(string: String): String {
        if(!hasArray(string))
            return ""

        //Replace square brackets of array with regular so it's easier to differentiate
        var input = string
        input = input.replaceFirst(", [", ", (")
        input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")

        val arraySplit = input.split("(", ")")
        return arraySplit[1]//Always the second index
    }

    private fun replaceArray(input: String, array: String): String {
        return input.replaceFirst(array, "\$array")
    }

    /**
     * Iterates pattern matching for the remainder containers
     * @return list of individual container strings
     */
    private fun extractContainers(string: String): ArrayList<String> {
        var array = string
        val containers = arrayListOf<String>()
        var index = 0

        //Nature of pattern matches deepest level first then works it's way upwards
        while(array.contains("[")) {//while has more containers
            val matcher = pattern.matcher(array)

            while (matcher.find()) {
                val match = matcher.group()
                containers.add(match)
                array = array.replace(match, "\$${index++}")
            }
        }
        return containers
    }

    /**
     * Replaces container strings with placeholder indices
     */
    private fun replaceContainers(string: String, containers: ArrayList<String>): String {
        var array = string
        containers.forEachIndexed { index, s -> array = array.replaceFirst(s, "\$$index") }
        return array
    }

    /**
     * Splits container variables
     * @return array of values
     */
    private fun getVariables(string: String): List<String> {
        return string.substring(11, string.length - 1).split(", ")
    }

    @Test
    fun all() {
        val input = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"], CONTAINER [false], true], CONTAINER [2, \"string\", false], CONTAINER [4]], 42, true]"//"""CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""

        if(hasArray(input)) {
            val array = extractArray(input)

            val first = replaceArray(input, array)

            val containers = extractContainers(array)

            val final = replaceContainers(array, containers)

            println("$first ${getVariables(first)}")

            println("\$array = $final")

            containers.forEachIndexed { index, s -> println("\$$index = $s ${getVariables(s)}") }
        }
    }

    private val emptyLast = "CONTAINER [1, \"one\", false, []]"
    private val oneLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]]]"
    private val twoLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]]]"
    private val threeLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]]]"

    private val empty = "CONTAINER [1, \"one\", false, [], 42]"
    private val one = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]], 42]"
    private val two = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]], 42]"
    private val three = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]], 42]"

    @Test
    fun hasArray() {
        Assert.assertFalse(hasArray(emptyLast))
        Assert.assertTrue(hasArray(oneLast))
        Assert.assertTrue(hasArray(twoLast))

        Assert.assertFalse(hasArray(empty))
        Assert.assertTrue(hasArray(one))
        Assert.assertTrue(hasArray(two))
    }

    @Test
    fun extractArray() {
        Assert.assertTrue(extractArray(empty).isEmpty())
        Assert.assertTrue(extractArray(emptyLast).isEmpty())

        Assert.assertEquals(extractArray(oneLast), "CONTAINER [2, \"two\"]")
        Assert.assertEquals(extractArray(twoLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
        Assert.assertEquals(extractArray(threeLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
        Assert.assertEquals(extractArray(one), "CONTAINER [2, \"two\"]")
        Assert.assertEquals(extractArray(two), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
        Assert.assertEquals(extractArray(three), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
    }

    @Test
    fun replaceArray() {
        val last = "CONTAINER [1, \"one\", false, [\$array]]"
        val first = "CONTAINER [1, \"one\", false, [\$array], 42]"
        Assert.assertEquals(replaceArray(oneLast, "CONTAINER [2, \"two\"]"), last)
        Assert.assertEquals(replaceArray(twoLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), last)
        Assert.assertEquals(replaceArray(threeLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), last)

        Assert.assertEquals(replaceArray(one, "CONTAINER [2, \"two\"]"), first)
        Assert.assertEquals(replaceArray(two, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), first)
        Assert.assertEquals(replaceArray(three, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), first)
    }

    @Test
    fun extractContainers() {
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
    }
}

对于正则表达式来说,这是一个非常糟糕的用例。如果您的容器对象可以具有任意深度的自嵌套,那么可能没有模式可以一致地描述它。因为您已经在使用Java,所以用几行单独的代码来处理这个对象应该非常简单。这有点离题,但实际上是否有一个[就在容器之前]?它看起来像[应该跟在单词CONTAINER后面。@CAustin我最初也这么认为,我不知道如何在不影响内部分隔符的情况下按分隔符分割,你能举个例子吗?正则表达式似乎更适合,因为它是一种模式,我只是不知道正则表达式中递归的程度。@zhh是的,因为它是数组中容器的数组变量。是否要解析整数?无法确定42是否与输出中的第一个或第二个容器分开。我不知道split可以接受多个参数,这有助于找到解决方案,谢谢。
import org.junit.Assert
import org.junit.Test
import java.util.regex.Pattern

class ContainerTest {

    private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")

    /**
     * Checks if string contains a full array in the middle or at the end of the container values
     * @return whether a verified container contains an array
     */
    private fun hasArray(string: String): Boolean {
        return string.contains(", [") && (string.contains("]], ") || string.endsWith("]]]"))
    }

    /**
     * Replaces last occurrence of a substring
     * Credit: https://stackoverflow.com/a/16665524/2871826
     */
    private fun replaceLast(string: String, substring: String, replacement: String): String {
        val index = string.lastIndexOf(substring)
        return if (index == -1) string else string.substring(0, index) + replacement + string.substring(index + substring.length)
    }

    /**
     * Splits root container and returns string contents of it's array
     */
    private fun extractArray(string: String): String {
        if(!hasArray(string))
            return ""

        //Replace square brackets of array with regular so it's easier to differentiate
        var input = string
        input = input.replaceFirst(", [", ", (")
        input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")

        val arraySplit = input.split("(", ")")
        return arraySplit[1]//Always the second index
    }

    private fun replaceArray(input: String, array: String): String {
        return input.replaceFirst(array, "\$array")
    }

    /**
     * Iterates pattern matching for the remainder containers
     * @return list of individual container strings
     */
    private fun extractContainers(string: String): ArrayList<String> {
        var array = string
        val containers = arrayListOf<String>()
        var index = 0

        //Nature of pattern matches deepest level first then works it's way upwards
        while(array.contains("[")) {//while has more containers
            val matcher = pattern.matcher(array)

            while (matcher.find()) {
                val match = matcher.group()
                containers.add(match)
                array = array.replace(match, "\$${index++}")
            }
        }
        return containers
    }

    /**
     * Replaces container strings with placeholder indices
     */
    private fun replaceContainers(string: String, containers: ArrayList<String>): String {
        var array = string
        containers.forEachIndexed { index, s -> array = array.replaceFirst(s, "\$$index") }
        return array
    }

    /**
     * Splits container variables
     * @return array of values
     */
    private fun getVariables(string: String): List<String> {
        return string.substring(11, string.length - 1).split(", ")
    }

    @Test
    fun all() {
        val input = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"], CONTAINER [false], true], CONTAINER [2, \"string\", false], CONTAINER [4]], 42, true]"//"""CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""

        if(hasArray(input)) {
            val array = extractArray(input)

            val first = replaceArray(input, array)

            val containers = extractContainers(array)

            val final = replaceContainers(array, containers)

            println("$first ${getVariables(first)}")

            println("\$array = $final")

            containers.forEachIndexed { index, s -> println("\$$index = $s ${getVariables(s)}") }
        }
    }

    private val emptyLast = "CONTAINER [1, \"one\", false, []]"
    private val oneLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]]]"
    private val twoLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]]]"
    private val threeLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]]]"

    private val empty = "CONTAINER [1, \"one\", false, [], 42]"
    private val one = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]], 42]"
    private val two = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]], 42]"
    private val three = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]], 42]"

    @Test
    fun hasArray() {
        Assert.assertFalse(hasArray(emptyLast))
        Assert.assertTrue(hasArray(oneLast))
        Assert.assertTrue(hasArray(twoLast))

        Assert.assertFalse(hasArray(empty))
        Assert.assertTrue(hasArray(one))
        Assert.assertTrue(hasArray(two))
    }

    @Test
    fun extractArray() {
        Assert.assertTrue(extractArray(empty).isEmpty())
        Assert.assertTrue(extractArray(emptyLast).isEmpty())

        Assert.assertEquals(extractArray(oneLast), "CONTAINER [2, \"two\"]")
        Assert.assertEquals(extractArray(twoLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
        Assert.assertEquals(extractArray(threeLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
        Assert.assertEquals(extractArray(one), "CONTAINER [2, \"two\"]")
        Assert.assertEquals(extractArray(two), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
        Assert.assertEquals(extractArray(three), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
    }

    @Test
    fun replaceArray() {
        val last = "CONTAINER [1, \"one\", false, [\$array]]"
        val first = "CONTAINER [1, \"one\", false, [\$array], 42]"
        Assert.assertEquals(replaceArray(oneLast, "CONTAINER [2, \"two\"]"), last)
        Assert.assertEquals(replaceArray(twoLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), last)
        Assert.assertEquals(replaceArray(threeLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), last)

        Assert.assertEquals(replaceArray(one, "CONTAINER [2, \"two\"]"), first)
        Assert.assertEquals(replaceArray(two, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), first)
        Assert.assertEquals(replaceArray(three, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), first)
    }

    @Test
    fun extractContainers() {
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
        Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
    }
}