【问题标题】:Splitting mikrotik script into an key/value php array将 mikrotik 脚本拆分为键/值 php 数组
【发布时间】:2021-01-19 16:47:15
【问题描述】:

比方说,我在 mikrotik 路由器下面有这个脚本,我想提取一个包含键和值的数组,如果另一个值包含 = 字符,该怎么做,

add name=100YER on-login=":do {:put \"a\";} on-error={};" rate-limit=256k/512k

结果应该是这样的:

$result=array ('name'=>'100YER', on-login=>':do {:put \"a\";} on-error={};', 'rate-limit'=>'256k/512k');

我使用此正则表达式将其按 = 拆分,但问题在于登录值。

if (preg_match_all('/[^=]+/i', $response, $MATCHES) ){
        //
}

【问题讨论】:

    标签: php arrays regex mikrotik


    【解决方案1】:

    要改进@Thefourthbird 的模式,请使用PHP: Regex to ignore escaped quotes within quotes 的“最佳”技术中的智慧。这不仅在步数方面提高了模式效率,而且还更准确地区分了字面使用的反斜杠和转义使用的反斜杠。

    否则,我完全同意分支重置最适合将目标子字符串保持在preg_match_all() 的输出数组的一致列中。

    代码:(Demo)

    $string = <<<MIKROTIK
    add name=100YER on-login=":do {:put \"a\";} on-error={};" rate-limit=256k/512k
    MIKROTIK;
    
    var_export(
        preg_match_all(
            '~(\w+(?:-\w+)*)=(?|"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|([^" ]+))~',
            $string,
            $out
        )
        ? array_combine($out[1], $out[2])
        : []
    );
    

    输出:

    array (
      'name' => '100YER',
      'on-login' => ':do {:put \\"a\\";} on-error={};',
      'rate-limit' => '256k/512k',
    )
    

    【讨论】:

      【解决方案2】:

      您可以使用 2 个捕获组和一个分支重置组:

      (\w+(?:-\w+)*)=(?|"((?:[^"]+|(?<=\\)")++)"|([^"\s]+))
      

      说明

      • ( 捕获第 1 组
        • \w+(?:-\w+)* 匹配 1+ 个单词字符(可选地后跟 - 和 1+ 个单词字符)
      • )关闭第一组
      • = 字面匹配
      • (?|分支重置组
        • "( 匹配 " 并开始 第 2 组
          • (?:[^"]+|(?&lt;=\\)")++ 匹配除"\" 之外的任何字符
        • )" 关闭第 2 组并匹配 "
        • |或者
        • ([^"\s]+) 捕获group 3,匹配除" 或空白字符以外的任何字符
      • )关闭分支重置组

      Regex demo | Php demo

      例如

      $re = '/(\w+(?:-\w+)*)=(?|"((?:[^"]+|(?<=\\\\)")++)"|([^"\s]+))/';
      $str = 'add name=100YER on-login=":do {:put \\"a\\";} on-error={};" rate-limit=256k/512k';
      
      preg_match_all($re, $str, $matches);
      $result = array_combine($matches[1], $matches[2]);
      print_r($result);
      

      输出

      Array
      (
          [name] => 100YER
          [on-login] => :do {:put \"a\";} on-error={};
          [rate-limit] => 256k/512k
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-17
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 2013-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多