Regex для чтения ini с PHP - PullRequest
       0

Regex для чтения ini с PHP

1 голос
/ 14 октября 2010

Пример файла INI

[SAMPLE.jpg]
faces=rect64(c18f4c8ef407851e),d4ff0a020be5c3c0;rect64(534a06d429ae627),dff6163dfd9d4e41;rect64(b9c100fae46b3046),e1059dcf6672a2b3;rect64(7b5105daac3a3cf4),4fc7332c107ffafc;rect64(42a036a27062a6c),ef86c3326c143248;rect64(31f4efe3bd68fd8),90158b3d3b65dc9b;rect64(327904e0614d390d),43cbda6e92fcb63e;rect64(4215507584ae9b8c),15b6a967e857f334;rect64(895d4efeb8b68425),5c4ff70ac70b27d3
backuphash=285
[Size.JPG]
faces=rect64(f73101cd554ca7f),43cbda6e92fcb63e
backuphash=38150
[ints.jpg]
faces=rect64(45c213047999593c),e1059dcf6672a2b3
backuphash=19801
[SC.jpg]
faces=rect64(993f2dfdab7f5166),e1059dcf6672a2b3;rect64(4b002f365a004c1b),ef86c3326c143248;rect64(bbffbb9fcb7fda25),ef86c3326c143248;rect64(bbbf9b10cb7fb996),90158b3d3b65dc9b;rect64(bbffdc97cb3ffa4c),4fc7332c107ffafc;rect64(5ec0306f734058b9),43cbda6e92fcb63e;rect64(65c06969827fa12b),15b6a967e857f334;rect64(bbff59f2cbbf7878),15b6a967e857f334;rect64(bbff7a81cb3f989f),43cbda6e92fcb63e
backuphash=9829
[karate.jpg]
faces=rect64(20823e7a6186b30b),15b6a967e857f334;rect64(92cb3e7ad34cb30b),15b6a967e857f334
backuphash=34154

Алгоритм для картины

[$name_of_picture]
faces=rect64($hex1_1),$hex1_2;rect64($hex2_1),hex2_2;....rect64($hexn_1),hexn_2;

Мне интересно читать только те части, которые назначены $ var_name .. в приведенном выше коде. Как мне это сделать?

Обновление

Использование parse ini

<?php
//code from php.net

// Parse without sections
$ini_array = parse_ini_file("pic.ini");
print_r($ini_array);

// Parse with sections
$ini_array = parse_ini_file("pic.ini", true);
print_r($ini_array);

?>

выход

Предупреждение: ошибка разбора в pic.ini включена строка 2 в C: \ tezt \ up.php в строке 26

Предупреждение: ошибка разбора в pic.ini включена строка 2 в C: \ tezt \ up.php в строке 30

Update2

<?php

function new_parse_ini($f)
{

    // if cannot open file, return false
    if (!is_file($f))
        return false;

    $ini = file($f);

    // to hold the categories, and within them the entries
    $cats = array();

    foreach ($ini as $i) {
        if (@preg_match('/\[(.+)\]/', $i, $matches)) {
            $last = $matches[1];
        } elseif (@preg_match('/(.+)=(.+)/', $i, $matches)) {
            $cats[$last][$matches[1]] = $matches[2];
        }
    }

    return $cats;

}

?>

выход

Array ([SAMPLE.jpg] => Array ( [лица] => rect64 (c18f4c8ef407851e), d4ff0a020be5c3c0; rect64 (534a06d429ae627), dff6163dfd9d4e41; rect64 (b9c100fae46b3046), e1059dcf6672a2b3; rect64 (7b5105daac3a3cf4), 4fc7332c107ffafc; rect64 (42a036a27062a6c), ef86c3326c143248; rect64 (31f4efe3bd68fd8), 90158b3d3b65dc9b; rect64 (327904e0614d390d), 43cbda6e92fcb63e; rect64 (4215507584ae9b8c), 15b6a967e857f334; rect64 (895d4efeb8b68425), 5c4ff70ac70b27d3 [backuphash] => 285) [Size.JPG] => Массив ([лица] => rect64 (f73101cd554ca7f), 43cbda6e92fcb63e [backuphash] => 38150) [ints.jpg] => Массив ([лица] => rect64 (45c213047999593c), e1059dcf6672a2b3 [backuphash] => 19801) [SC.jpg] => Массив ([лица] => rect64 (993f2dfdab7f5166), e1059dcf6672a2b3; rect64 (4b002f365a004c1b), ef86c3326c143248; rect64 (bbffbb9fcb7fda25), ef86c3326c143248; rect64 (bbbf9b10cb7fb996), 90158b3d3b65dc9b; rect64 (bbffdc97cb3ffa4c), 4fc7332c107ffafc; rect64 (5ec0306f734058b9), 43cbda6e92fcb63e; rect64 (65c06969827fa12b), 15b6a967e857f334; rect64 (bbff59f2cbbf7878), 15b6a967e857f334; rect64 (bbff7a81cb3f989f), 43cbda6e92fcb63e [backuphash] => 9829) [karate.jpg] => Массив ([лица] => rect64 (20823e7a6186b30b), 15b6a967e857f334; rect64 (92cb3e7ad34cb30b), 15b6a967e857f334 [backuphash] => 34154))

Пока все хорошо. Спасибо вам, ребята. Этот вопрос связан с другим моим вопросом Автоматическое распознавание лиц с использованием API Picasa для извлечения отдельных изображений

Ответы [ 6 ]

7 голосов
/ 14 октября 2010

PHP имеет встроенную функцию для анализа INI-файлов. parse_ini_file()

2 голосов
/ 14 октября 2010

Подробно о ответе Пекки :

  1. Анализ файла через $ini = parse_ini_file(<file>, true)
  2. Выбор faces=... по имени изображения: $str = $ini[$name_of_picture]['faces']
  3. explode() на ;
  4. Итерируйте их и взрывайте на ,

(Вы можете убедиться, что раздел ($name_of_picture) и директива (faces) существуют, см. isset().)

2 голосов
/ 14 октября 2010

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

В этом случае у вас есть встроенная в PHP функциональность, которая делает это за вас.

1 голос
/ 14 октября 2010

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

^\s*\[([^\]]+)\]

Вы можете ссылаться на текст в квадратных скобках, используя $1 в заменяемой части или \1, если вы ссылаетесь в поисковой части.

Однако я согласен, что вы должны использовать встроенную библиотеку PHP для анализа INI-файлов для серьезных проектов.

0 голосов
/ 28 марта 2017

Моя функция основана на функции OP, но в некоторых точках она исправлена.Он разбирает текстовое содержимое .ini в массив.Он не обрабатывает значения категорий, правильно обрабатывает кавычки вокруг значений и допускает пустые строки, например.

function stripQuotes($text) {
    return preg_replace('/^(\'(.*)\'|"(.*)")$/', '$2$3', $text);
}


function ini2array($s) {
    $ini=explode("\n", $s);

    // to hold the categories, and within them the entries
    $cats = array();
    $last = '';

    foreach ($ini as $i) {
        if (@preg_match('/\[(.+)\]/', $i, $matches)) {
            $last=stripQuotes(trim($matches[1]));
        } elseif (@preg_match('/(.+)=(.+)/', $i, $matches)) {
            $key=stripQuotes(trim($matches[1]));
            if (strlen($key)>0) {
                $val=stripQuotes(trim($matches[2]));
                if (strlen($last) > 0) {
                    $cats[$last][$key]=trim($val);
                } else {
                    $cats[$key]=trim($val);
                }
            }
        }
    }

    return $cats;
}
0 голосов
/ 29 сентября 2015

Пожалуйста, проверьте следующее ini regex из drush tool:

class ParserIni implements ParserInterface {
  /**
   * Regex for parsing INI format.
   */
  private static $iniRegex = '
    @^\s*                           # Start at the beginning of a line, ignoring leading whitespace
    ((?:
      [^=;\[\]]|                    # Key names cannot contain equal signs, semi-colons or square brackets,
      \[[^\[\]]*\]                  # unless they are balanced and not nested
    )+?)
    \s*=\s*                         # Key/value pairs are separated by equal signs (ignoring white-space)
    (?:
      ("(?:[^"]|(?<=\\\\)")*")|     # Double-quoted string, which may contain slash-escaped quotes/slashes
      (\'(?:[^\']|(?<=\\\\)\')*\')| # Single-quoted string, which may contain slash-escaped quotes/slashes
      ([^\r\n]*?)                   # Non-quoted string
    )\s*$                           # Stop at the next end of a line, ignoring trailing whitespace
    @msx';

  /**
   * {@inheritdoc}
   */
  public static function parse($data) {
    if (preg_match_all(self::$iniRegex, $data, $matches, PREG_SET_ORDER)) {
      $info = array();
      foreach ($matches as $match) {
        // Fetch the key and value string.
        $i = 0;
        foreach (array('key', 'value1', 'value2', 'value3') as $var) {
          $$var = isset($match[++$i]) ? $match[$i] : '';
        }
        $value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3;
        // Parse array syntax.
        $keys = preg_split('/\]?\[/', rtrim($key, ']'));
        $last = array_pop($keys);
        $parent = &$info;
        // Create nested arrays.
        foreach ($keys as $key) {
          if ($key == '') {
            $key = count($parent);
          }
          if (isset($merge_item) && isset($parent[$key]) && !is_array($parent[$key])) {
            $parent[$key] = array($merge_item => $parent[$key]);
          }
          if (!isset($parent[$key]) || !is_array($parent[$key])) {
            $parent[$key] = array();
          }
          $parent = &$parent[$key];
        }
        // Handle PHP constants.
        if (defined($value)) {
          $value = constant($value);
        }
        // Insert actual value.
        if ($last == '') {
          $last = count($parent);
        }
        if (isset($merge_item) && isset($parent[$last]) && is_array($parent[$last])) {
          $parent[$last][$merge_item] = $value;
        }
        else {
          $parent[$last] = $value;
        }
      }
      return $info;
    }
  }
}

Тогда используйте это как:

$parsed = ParserIni::parse($data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...