PHP - зациклить файл CSV и проверить пустые строки - PullRequest
1 голос
/ 05 апреля 2019

Я пытаюсь прочитать CSV-файл и извлечь данные благодаря различным регулярным выражениям. У меня нет доступа к импортированному содержимому CSV-файла.

Однако возможно, что одна или несколько строк пусты. Для этого можно использовать функцию обрезки (). Проблема в том, чтобы узнать, как адаптировать мои различные массивы для восстановления пустых строк

enter image description here

В этом примере две строки для номера телефона пусты, так как я могу это определить и как вставить эти пустые строки в массив моих телефонов?

Например, если я сделаю:

foreach($fullNames as $fullName)
{
    echo $fullName."<br>";
}

foreach($phones as $phone)
{
    echo $phone."<br>";
}

Результат будет:

{Марк Вадор, Марк Вадор, Марк Вадор, Марк Вадор, Марк Вадор}

{0692 10 10 10, 0692 10 10 10,0692 10 10 10}

что я хочу достичь, это:

{Марк Вадор, Марк Вадор, Марк Вадор, Марк Вадор, Марк Вадор}

{0692 10 10 10,, 0692 10 10 10,, 0692 10 10 10}

$emptyValue = "";

if (($handle = fopen($loadedSheetName.'.csv', "r")) !== FALSE) 
{ 
    fgetcsv($handle);

    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) 
    {   
        $col = count($data);

        for($c = 0; $c < $col; $c++)
        {
            $phones = array();
            $mails = array();
            $zipcodes = array();
            $fullNames = array();

            if ('' === trim($data[$c]))
            {
                $emptyValue = "";
            }

            if(preg_match('/^(0)(692|693|262)(\d{6})$/', $data[$c], $matches))
            {
                $phones[] = "+262".$matches[2].$matches[3];
            }

            if(preg_match('/^(0)(692|693|262)( )(\d{2})( )(\d{2})( )(\d{2})$/', $data[$c], $matches))
            {
                $phones[] = "+262".$matches[2].$matches[4].$matches[6].$matches[8];
            }

            if(preg_match('/^(0)(692|693|262)( )(\d{2})( )(\d{2})( )(\d{2})(\/)(0)(692|693|262)( )(\d{2})( )(\d{2})( )(\d{2})$/', $data[$c], $matches))
            {
                $phones[] = "+262".$matches[2].$matches[4].$matches[6].$matches[8].$matches[9]."+262".$matches[11].$matches[13].$matches[15].$matches[17];
            }

            if(preg_match('/^([^\W][a-zA-Z0-9_]+)(\.[a-zA-Z0-9_]+)*(\@)([a-zA-Z0-9_]+)*(\.[a-zA-Z]{2,4})$/', $data[$c], $matches))
            {
                $mails[] = $matches[0];
            } 

            if(preg_match('/^(Sainte|Saint|saint|sainte)(-)([a-zA-z]+)$/', $data[$c], $matches))
            {
                $zipcodes[] = $matches[0];
            }

            if(preg_match('/^(([a-zA-Z\W]+)( )([a-zA-Z\W]+))$/', $data[$c], $matches))
            {
                $fullNames[] = $matches[0];
            }

            if(preg_match('/^(([a-zA-Z\W]+)( )([a-zA-Z\W]+)( )([a-zA-Z\W]+))$/', $data[$c], $matches))
            {  
                $fullNames[] = $matches[0];
            }
        }
    }

    fclose($handle);
}

1 Ответ

1 голос
/ 05 апреля 2019

То, что вы показали нам здесь, содержит много плохих практик. Трудно посоветовать, как вы должны решать проблему, когда мы не знаем, в чем проблема; конечный результат - не заполнение некоторых массивов php - это всего лишь механизм временного хранения.

Ваш вопрос также несколько сбивает с толку - "строка" по отношению к CSV-файлу описывает запись, а запись состоит из полей (или иногда значений атрибутов в зависимости от характера CSV-файла). Из вашего повествования то, что вы описываете как «строку», представляет собой поле или значение атрибута.

Каждая запись в CSV-файле сохраняет связь между полями компонента по строке, в которой она появляется. Но сами поля могут содержать встроенные разрывы строк, если они заключены в кавычки или экранированы.

Не заполняя пустые значения в ваше промежуточное представление, вы нарушаете эту связь.

что я хочу достичь, это

То есть вы хотите сохранить пустые значения, а не пропускать их. Поэтому добавьте пустое значение в массив.

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

Результат будет:

Нет, не будет. Код, который вы нам показали, сбрасывает выходные массивы каждый раз, когда вы читаете строку данных из файла.

Если вы двигаетесь

        $phones = array();
        $mails = array();
        $zipcodes = array();
        $fullNames = array();

За пределами цикла while вы получите что-то близкое к тому, что вы описываете.

Обычный способ решения проблемы - использовать else if, чтобы сделать каждое из ваших условий соответствия эксклюзивным:

        if ('' === trim($data[$c]))
        {
            $emptyValue = "";
        }
        else if(preg_match('/^(0)(692|693|262)(\d{6})$/', $data[$c], $matches))
        {
            $phones[] = "+262".$matches[2].$matches[3];
        }
        else if if(preg_match('/^(0)(692|693|262)( )(\d{2})( )(\d{2})( )(\d{2})$/', $data[$c], $matches))
        {
            $phones[] = "+262".$matches[2].$matches[4].$matches[6].$matches[8];
        ...

Но ваш код в настоящее время написан для размещения полей, представленных в любом порядке в записи. Хотя в действительности это может иметь место, это очень необычный сценарий, который основывается на всех присутствующих полях (не в этом случае) и не дублируется. Если в вашем входном файле есть такая нехватка структуры, вы напрасно тратите время на написание кода для автоматизации анализа данных - даже если вы решите эту проблему, вы столкнетесь с дальнейшей болью. Вывоз мусора, Вывоз мусора.

Однако, как чисто академическое упражнение, если мы допустим, что подразумеваемые предикаты применяются, это все равно тривиально , чтобы решить. Просто отследите исходную ассоциацию записи в своем коде:

if (($handle = fopen($loadedSheetName.'.csv', "r")) !== FALSE) { 
  $phones = array();
  $mails = array();
  $zipcodes = array();
  $fullNames = array();
  $record=0;
  fgetcsv($handle);
  while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {   
    $record++;
    $col = count($data);
    for($c = 0; $c < $col; $c++) {
        if(preg_match('/^(0)(692|693|262)(\d{6})$/', $data[$c], $matches))
        {
           $phones[$record] = "+262".$matches[2].$matches[3];
        }
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...