Regex объединяет линии - PullRequest
0 голосов
/ 03 мая 2020

Учитывая следующую строку

45op0
tr ico
JJB Be
tyuh
113-4997
202076
acure
sala mandra

Я ищу следующий результат:

45op0;113-4997
tr ico;202076
JJB Be;acure
tyuh;sala mandra

В основном объедините 4 строки внизу с 4 вверху, в их исходный порядок, в ; отдельном списке.

Это регулярное выражение, которое у меня есть:

^((?:[^\r*\n]*[\r*\n]){4})([\s\S]*)

с заменой на:

$1;$2

, как показано на this demo

Как видите, это не дает точного результата.

Любая помощь будет высоко ценится.

1 Ответ

1 голос
/ 03 мая 2020

Вы можете использовать регулярное выражение

^(.+)\r?\n(?=(?:.*\r?\n){3}(.+))

Демонстрация PCRE

Для приведенного примера есть четыре соответствия: 45op0, tr ico, JJB Be и tyuh. Каждый матч имеет две группы захвата. Первая группа захвата содержит само совпадение. Для первого совпадения (45op0) группа захвата 2 содержит 113-4997, что фиксируется в положительном прогнозе. Затем содержимое двух групп захвата можно объединить, разделив их точкой с запятой, чтобы получить 45op0;113-4997

Аналогично, для второй группы захвата совпадений 2 содержит 202076 и т. Д.

Когда строка 113-4997 достигнута, она сохраняется в cap grp 1, следующие три строки используются, а затем выполняется регулярное выражение, потому что за непустой строкой нет следующей. В следующих строках регулярное выражение не выполняется, поскольку оно не может пропустить три строки.

Модуль регулярных выражений PCRE выполняет следующие операции.

^(.+)          match a line with 1+ chars, excl. line terminators,
               in cap grp 1 
\r?\n          match the newline and possible carriage return
(?=            begin a positive lookahead
  (?:.*\r?\n)  match an entire line in a non-cap group          
  {3}          execute the non-cap group 3 times (skip 3 lines)
  (.+)         match a line with 1+ chars, excl. line terminators,
               in cap grp 2
)              end positive lookahead
...