Сохраняйте текст внутри цитаты без изменений при разделении текста - PullRequest
1 голос
/ 13 июля 2020

Мне нужны данные в строке [$ str], заключенной в кавычки, чтобы не разбивать. В этом случае «Бухгалтерская компания» должна храниться в одной строке, а не разворачиваться.

<?php

$str =
'#PROGRAM   "Accounting company"    98.2
 #GENERATED     2020715 "SE"';

$data = explode("\n", $str);

foreach($data as &$value){
    $value = preg_split("/\s+/", $value);
}

var_dump($data);

Результат:

array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(8) "#PROGRAM"
    [1]=>
    string(11) ""Accounting" // Unwanted split
    [2]=>
    string(8) "company""  // Unwanted split
    [3]=>
    string(4) "98.2"
  }
  [1]=>
  &array(4) {
    [0]=>
    string(0) ""
    [1]=>
    string(10) "#GENERATED"
    [2]=>
    string(7) "2020715"
    [3]=>
    string(4) ""SE""
  }
}

Требуемый результат:

array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(8) "#PROGRAM"
    [1]=>
    string(18) ""Accounting company"
    [2]=>
    string(4) "98.2"
  }
  [1]=>
  &array(4) {
    [0]=>
    string(0) ""
    [1]=>
    string(10) "#GENERATED"
    [2]=>
    string(7) "2020715"
    [3]=>
    string(4) ""SE""
  }
}

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вы можете использовать шаблон SKIP FAIL, чтобы пропустить совпадающие значения от открывающей до закрывающей двойной кавычки, а затем сопоставить 1+ горизонтальных пробельных символов для разделения на

"[^"]*"(*SKIP)(*FAIL)|\h+

Regex demo

$str =
    '#PROGRAM   "Accounting company"    98.2
 #GENERATED     2020715 "SE"';

$data = explode("\n", $str);

foreach($data as &$value){
    $value = preg_split("/\"[^\"]*\"(*SKIP)(*FAIL)|\h+/", $value);
}

print_r($data);

Вывод

Array
(
    [0] => #PROGRAM
    [1] => "Accounting company"
    [2] => 98.2
)
Array
(
    [0] => 
    [1] => #GENERATED
    [2] => 2020715
    [3] => "SE"
)

Если вам не нужна пустая запись во втором массиве, вы можете использовать флаг PREG_SPLIT_NO_EMPTY:

$value = preg_split("/\"[^\"]*\"(*SKIP)(*FAIL)|\h+/", $value, -1, PREG_SPLIT_NO_EMPTY);

Php демонстрация

0 голосов
/ 13 июля 2020

Здесь решение без регулярного выражения

$str =
'#PROGRAM   "Accounting company"    98.2
 #GENERATED     2020715 "SE"';

$quoted = false;
$index = 0;
$data = [];
$rows = explode("\n", $str);

foreach($rows as $row) {
    $temp = [];
    for ($i = 0; $i < strlen($row); $i++) {
        if ($row[$i] === "\"") $quoted = !$quoted;
        if ($row[$i] === " " && !$quoted) {
            $index++;
            continue;
        }
        
        $temp[$index] = ($temp[$index] ?? "") . $row[$i];
    }
    
    $data[] = array_values($temp);
}

var_dump($data);

Результат

array(2) {
  [0]=>
  array(3) {
    [0]=>
    string(8) "#PROGRAM"
    [1]=>
    string(20) ""Accounting company""
    [2]=>
    string(4) "98.2"
  }
  [1]=>
  array(3) {
    [0]=>
    string(10) "#GENERATED"
    [1]=>
    string(7) "2020715"
    [2]=>
    string(4) ""SE""
  }
}

Демо

Тем не менее, все еще пытаемся найти решение с регулярным выражением :) 1011 *

Если вы хотите сохранить пустой элемент в [1] [0]: Демо

...