【问题标题】:Regex for Reading ini with PHP使用 PHP 读取 ini 的正则表达式
【发布时间】:2011-04-25 11:18:47
【问题描述】:

示例 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.. 分配的部分。我该怎么办?

更新

使用解析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 中解析错误 第 26 行 C:\tezt\up.php 中的第 2 行

警告:在 pic.ini 中解析错误 第 30 行 C:\tezt\up.php 中的第 2 行

更新2

<?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;

}

?>

输出

数组 ( [SAMPLE.jpg] => 数组 ( [面孔] => 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 [备份] => 285 ) [大小.JPG] => 数组([面孔] => rect64(f73101cd554ca7f),43cbda6e92fcb63e [备份] => 38150 ) [ints.jpg] => 数组([面孔] => rect64(45c213047999593c),e1059dcf6672a2b3 [备份] => 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 [备份] => 9829 ) [空手道.jpg] => 数组([面孔] => rect64(20823e7a6186b30b),15b6a967e857f334;rect64(92cb3e7ad34cb30b),15b6a967e857f334 [备份] => 34154 ) )

到目前为止一切顺利。谢谢你们。 这个问题与我的另一个问题有关 Automatic face detection using Picasa API to extract individual images

【问题讨论】:

    标签: php regex parsing


    【解决方案1】:

    PHP 有一个用于解析 INI 文件的内置函数。 parse_ini_file()

    【讨论】:

    • 打败我:-S 记住 $process_sections = true(第二个参数)
    • 确实如此,然后是 explode; 等等。所有这些都比正则表达式更具可读性和可维护性,甚至可能更快。
    • @Wrikken 啊,我只是将其发布为答案。嗯,不是我的日子:(
    • 我在第 2 行遇到解析错误。尝试解析上述文件时
    • @Pekka 我用一个使用正则表达式的工作函数更新了这个问题。做评论。
    【解决方案2】:

    细说Pekka的answer

    1. 通过$ini = parse_ini_file(&lt;file&gt;, true)解析文件
    2. 按图片名称选择faces=...$str = $ini[$name_of_picture]['faces']
    3. explode();
    4. 迭代那些并在,上爆炸

    (您可能需要确保部分 ($name_of_picture) 和指令 (faces) 存在,请参阅 isset()。)

    【讨论】:

      【解决方案3】:

      并非所有与字符串相关的内容都最好用正则表达式来回答。

      在这种情况下,您可以使用 PHP 内置的功能为您执行此操作。

      http://php.net/manual/en/function.parse-ini-file.php

      【讨论】:

      • 实际上,正则表达式对于解析 INI 文件很有意义。然而,程序员似乎对编写正则表达式的可能性视而不见,因为这些正则表达式从来没有像现有的经过测试的工作代码那样是一个好的选择。
      【解决方案4】:

      如果你好奇如何用正则表达式解析它,或者你懒得写比较长的代码,这里使用正则表达式:

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

      您可以在替换部分使用$1 来引用方括号内的文本,如果您在搜索部分引用,则可以使用\1

      但是,我同意您应该使用内置的 PHP 库来解析严肃项目的 INI 文件。

      【讨论】:

        【解决方案5】:

        请检查drush工具中的以下ini正则表达式:

        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);
        

        【讨论】:

          【解决方案6】:

          我的功能基于 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;
          }
          

          【讨论】:

            猜你喜欢
            • 2023-04-05
            • 1970-01-01
            • 1970-01-01
            • 2014-03-29
            • 1970-01-01
            • 2012-07-12
            • 1970-01-01
            • 2019-11-09
            • 2020-09-06
            相关资源
            最近更新 更多