Поиск чисел с запятой в виде десятичной точки в массиве

#php #regex

#php #регулярное выражение

Вопрос:

Я должен выполнить поиск в файле Excel и получить числа, в которых запятая является десятичной точкой, и преобразовать ее в десятичную точку.(пример: 23,56 -> 23.56, 23123,566 -> 23123.566). Я уже экспортировал файл Excel в .csv и поместил все содержимое в массивы, но у меня возникли проблемы с поиском чисел с запятой. Вот как выглядит один из моих массивов:

     Array
    (
        [A1] => 1
        [A2] => 123123
        [A3] => dasdadwa
        [A4] => 6,7
        [A5] => 24f,5
        [A6] => f5,5
        [A7] => dasdad,fsdfsdfsfsasada dasdasd
        [A8] => aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
        [A9] => dasdasd
        [A10] => q231e
        [A11] => 
        [A12] => 0
        [A13] => 
        [A14] => 
        [A15] => 1
        [A16] => 123123
        [A17] => dasdadwa
        [A18] => 6,7
        [A19] => 24f,5
        [A20] => f5,5
        [A21] => dasdad,fsdfsdfsfsasada dasdasd
        [A22] => 
        [A23] => 
        [A24] => q231e
        [A25] => 
        [A26] => 0
        [A27] => 
        [A28] => 
        [A29] => 1
        [A30] => 123123
        [A31] => dasdadwa
        [A32] => 6,7
        [A33] => 24f,5
        [A34] => f5,5
        [A35] => dasdad,fsdfsdfsfsasada dasdasd
        [A36] => 
        [A37] => 
        [A38] => q231e
        [A39] => 
        [A40] => 
        [A41] => 
        [A42] => 
    )
  

Меня интересуют только символы, которые содержат только цифры и запятую, но это проблематично, потому что эти записи являются строками. Я пытался возиться с регулярным выражением, но я просто не мог заставить его работать.
Вот что у меня есть до сих пор:

     function csv_to_array($filename='', $delimiter=',')
    {
        if(!file_exists($filename) || !is_readable($filename))
            return FALSE;

        $header = NULL;
        $data = array();
        if (($handle = fopen($filename, 'r')) !== FALSE)
        {
            while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
            {
                if(!$header)
                    $header = $row;
                else
                    $data[] = array_combine($header, $row);
            }
            fclose($handle);
        }
        return $data;
    }

$contents = csv_to_array($filename.'.csv');

    foreach($contents as $val) 
    {

        //If $val is a number separated by comma
             //Replace comma with . (str_replace(',','.');, $val);)
    }
  

Ответ №1:

Просто простой шаблон, который заменит только ваш шаблон:

 //rest od your code and now:
foreach($contents as $key => $val) 
{
  $contents[$key] = preg_replace('/^(d ),(d )$/', '1.2', $val);
}
  

Этот код будет касаться только таких строк, как 2,3 . Строки, подобные этому ff,333 , не будут касаться

Комментарии:

1. Стоит добавить ссылку на php.net/manual/en/function.preg-replace.php

2. Похоже, проблема связана с форматированием немецких чисел, в котором также будут точки в качестве разделителей тысяч. Возможно, стоит обновить ваш ответ, чтобы поддержать их. Но я согласен, что preg_replace было бы правильным решением.

3. @R.Chappell ну, OP не упоминал о немецких числах в своем excel, поэтому я не уверен, следует ли мне усложнять этот шаблон reg

4. @nospor это правда, я, возможно, слишком много читал. Может быть, Себастьян расскажет нам подробнее.

5. @R.Chappell да, давайте подождем отзывов Себастьяна 🙂

Ответ №2:

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

 foreach($contents as $val) {
    // if $val is a number separated by comma
    if (preg_match('/^[0-9] ,[0-9] $/', $val) == 1) {
         // transform into float with two decimals and dot as decimal separator
         $float = number_format($val, 2, '.');
    }
}
  

Редактировать: обновленный шаблон регулярных выражений после комментариев.

Комментарии:

1. Ваш код будет неправильным для таких строк fff2,3

2. И если есть только один символ, вам действительно не нужно использовать {1}

3. Да, так лучше 🙂

Ответ №3:

Нравится это?

 foreach($contents as $val) 
{
    if (strpos($val, ',') !== false) {
        $val = str_replace(',', '.', $val);
    }
}
  

Комментарии:

1. Ваш код также заменит ff,333 на ff.333, что неверно