Предварительно добавить шаблон регулярного выражения для разделения и сопоставить класс case для разделения

Я хочу разделить следующую строку, которая принимает форму

val str = "X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8| |Z01|Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]|Z01|Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|]|Z02|02|z2|Str|Str|"

Эта строка всегда начинается с X, а позиции разделения - Z01, Z02, ..., Z0D.

str.split("""\|Z0[1|2|3|4|5|6|7|8|9|A|B|C|D]{1}\|""") foreach println

Здесь не может быть упорядочивания позиций Z01, ..., Z0D в строке.

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

X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8|
Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]
Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|]
02|z2|Str|Str|

Однако я хочу сопоставить X, Z01, ... с классами case. Поскольку нет упорядочивания, невозможно определить, в какой раздел класса case необходимо сопоставить (нельзя использовать длину отдельных разделений).

Я ожидаю, что мой раскол будет иметь следующий результат:

X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8|
Z01|[Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]|
Z01|[Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|]|
Z01|02|z2|Str|Str|

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

Например:

case class X( ....)
case class Z01(val1: String, val2: String, val3: String)
case class Z02(val1: Int, val2: String, val3: String,val4:String)
.................

X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8| сопоставляется с case class X а также Z01|[Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]| соответствует классу корпуса Z01

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

X
Array[Z01]
Array[Z02]
......
......

Как насчет простого на вид str.split("Z"), а затем его ручного анализа?

Jatin 01.06.2018 13:01

@Jatin Это фактически часть преобразования фрейма данных Spark. Я бы хотел сделать это за один проход.

Robert Knox 01.06.2018 14:17

Я не могу это подтвердить. Но может потребоваться меньшее количество тактовых циклов. Regex - серийный убийца времени. Разделение на один символ не вызывает внутреннее выражение регулярного выражения, а простую итерацию строки

Jatin 01.06.2018 15:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
39
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как насчет этой идеи?

val x = str.split("""\|Z0[1|2|3|4|5|6|7|8|9|A|B|C|D]{1}\|""") // actual string splits
val y = """\|Z0[1|2|3|4|5|6|7|8|9|A|B|C|D]{1}\|""".r.findAllIn(str).toArray // delimiters Array

val final_data = x.slice(1, x.size).zip(y).map(x => x._2+x._1).toList // taking actual splits except first one .... and then zipping and concatenating with delimiters like below. 
/*
    List(|Z01|Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|], |Z01|Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|], |Z02|02|z2|Str|Str|) */

первый | в final_data может быть удален с помощью subString

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

В качестве альтернативы это может быть вариант получения ваших значений путем их сопоставления:

(?:Z0[1-9A-D]|^X).*?(?=\|Z0[1-9A-D]|$)

Это соответствует:

  • (?:Z0[1-9A-D]|X\|) В группе без захвата сопоставьте Z0 и перечислите возможные варианты в классе символов или | X в начале ^ строки
  • .*? Соответствует любому символу один или несколько раз не жадно
  • (?=\|Z0[1-9A-D]|$) Положительный просмотр вперед, который утверждает, что далее следует вертикальная черта |, за которой следует Z0 и символ из списка символов или | в конце строки $.

Например:

val re = """(?:Z0[1-9A-D]|^X).*?(?=\|Z0[1-9A-D]|$)""".r
val str = "X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8| |Z01|Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]|Z01|Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|]|Z02|02|z2|Str|Str|"

re.findAllIn(str) foreach println

Это приведет к:

X|blnk_1|blnk_2|blnk_3|blnk_4|time1|time2|blnk_5|blnk_6|blnk_7|blnk_8| 
Z01|Str1|01|001|NE]|[HEX1|HEX2]|[NA|001:1000|123:456|[00]|]
Z01|Str2|02|002|NE]|[HEX3|HEX4]|[NA|002:1001|234:456|[01]|]
Z02|02|z2|Str|Str|

Демо

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