Регулярное выражение для извлечения объектов JSON из массива

Я работаю над собственным десериализатором JSON на Java и хотел бы создать ArrayList объектов, указанных в таком .json файле. Например, для следующего файла:

[
    {
        "name": "User1",
        "gender": "M"
    },
    {
        "name": "User2",
        "gender": "F"
    }
]

(...) Я хочу, чтобы моя программа на Java создавала структуру из двух объектов класса User, каждый из которых содержал бы соответствующие поля.

Мне удалось сделать это только с одним значением, упомянутым в файле (поэтому нет массива JSON, просто объект между {} и некоторыми парами ключ-значение), но со списком все становится сложнее. Подумал о том, чтобы разбить весь массив JSON на все его элементы и применить мой единственный алгоритм разбора JSON к каждому из них, а затем добавить их в ArrayList.

Моя идея должна работать, но моя проблема в том, что я не уверен, как правильно разбить этот массив JSON, используя метод Java split() для строк. Я также не так хорош в выражениях регулярных выражений, чтобы думать о правильном.

Думал разделить его на основе: content.split("},"), а затем добавить последний } к последнему элементу, но это также приведет к разделению внутри членов моих элементов JSON, если они ссылаются на другие объекты.

Мой вопрос будет заключаться в том, что в этом контексте будет правильным регулярным выражением, которое заставит Java правильно разделить мой массив JSON на несколько элементов JSON?

Я могу удалить скобки в начале и в конце файла, это не должно быть проблемой, так как это требует только простых манипуляций со строками, но я также хочу массив String[], каждый из которых содержит одного из моих двух пользователей, вместе с их данные.

Ожидаемый результат:

String1: { "name": "User1", "gender": "M" }
String2: { "name": "User2", "gender": "F" }

Разделение @Icarus запятой также разделит мои ключи, а я этого не хочу. Мне нужен массив String объектов JSON, а не ключей JSON

Mario Mateaș 18.11.2022 06:47

перебирать строку, нажимать переднюю скобку всякий раз, когда она есть, и выталкивать ее всякий раз, когда есть задняя скобка. всякий раз, когда стек пуст, возвращайте подстроку до этой точки

Icarus 18.11.2022 06:49

@Icarus Это действительно было бы решением, а не решением. Но нельзя ли сделать это намного проще в REGEX?

Mario Mateaș 18.11.2022 06:51
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если он довольно отформатирован в соответствии с вашим вопросом, вы можете использовать:

(?s)(?<=^    )\{.*?(?<=^    )}

Вот некоторый тестовый код:

String input  = "[\n" +
        "    {\n" +
        "        \"name\": \"User1\",\n" +
        "        \"gender\": \"M\"\n" +
        "    },\n" +
        "    {\n" +
        "        \"name\": \"User2\",\n" +
        "        \"gender\": \"F\"\n" +
        "    }\n" +
        "]";
List<String> jsonObjects = Pattern.compile("(?sm)(?<=^    )\\{.*?(?<=^    )}")
  .matcher(input).results()
  .map(MatchResult::group)
  .map(str -> str.replaceAll("[\s\n]*(?!\",)", "")) // remove whitespace
  .collect(toList());

Вывод:

{"name":"User1","gender":"M"}
{"name":"User2","gender":"F"}

Другие вопросы по теме