代码之家  ›  专栏  ›  技术社区  ›  bestprogrammerintheworld

从字符串中的引号中提取时,如何包含等号和引号?

  •  0
  • bestprogrammerintheworld  · 技术社区  · 3 年前

    我有这个字符串:

    $shortcode = '[csvtohtml_create include_rows="1-10" 
    debug_mode="no" source_type="guess" path="largecsv" 
    source_files="test?output=csv"  csv_delimiter="," ]'
    

    我想检索属性及其值,甚至是引号中的等号或空格。

    How to explode a string but not within quotes in php?

    我有以下代码:

    $args = preg_split('/"[^"]+"(*SKIP)(*F)|\h+/', $shortcode);
       
    $attrs = [];
    foreach( $args as $item )
    {
        //Only use those items in array $args with = sign
        if ( strpos( $item , '=' ) !== false )
        {
            $sep = explode( '=', $item );
            $key = $sep[0];
            $value = $sep[1];
            $attrs[$key] = str_replace( '"', '', $value );
        }
    }
    
    $args = explode( '=', $sc );
    

    Array attrs
          "include_rows" => "1-10"
          "debug_mode" => "no"
          "source_type" => "guess"
          "path" => "largecsv"
          "source_files" => "test.csv?output"
          "csv_delimiter" => ","
     
    

    我想要的结果是:

    Array attrs
          "include_rows" => "1-10"
          "debug_mode" => "no"
          "source_type" => "guess"
          "path" => "largecsv"
          "source_files" => "test.csv?output=csv"
          "csv_delimiter" => ","
     
    

    我想我应该在这里的某个地方加上等号(或者是?=),但正则表达式不是我的强项。。。

    $args = preg_split('/"[^"]+"(*SKIP)(*F)|\h+/', $shortcode);
    
    3 回复  |  直到 3 年前
        1
  •  1
  •   Jacob Mulquin    3 年前

    你在正确的轨道上爆炸了等号。这个实现不需要 array_shift 那就去拿钥匙吧 implodes

    <?php
    
    $sc = '[csvtohtml_create include_rows="1-10" 
    debug_mode="no" source_type="guess" path="largecsv" 
    source_files="test?output=csv"  csv_delimiter="," ]';
    
    $args = array_filter(array_map('trim', preg_split('/"[^"]+"(*SKIP)(*F)|\h+/', $sc)));
    array_shift($args); // remove [csvtohtml
    array_pop($args); // remove ]
    
    $output = [];
    foreach ($args as $arg) {
        $explode = explode('=', $arg);
        $key = array_shift($explode);
        $value = str_replace('"', '', implode('=', $explode)); // remove str_replace if you want to keep the extra set of quotes
        $output[$key] = $value;
    }
    
    print_r($output);
    

    导致

    Array
    (
        [include_rows] => 1-10
        [debug_mode] => no
        [source_type] => guess
        [path] => largecsv
        [source_files] => test?output=csv
        [csv_delimiter] => ,
    )
    
        2
  •  0
  •   Wiktor Stribiżew    3 年前

    可以使用匹配属性名称及其值

    ([^\s=]+)=(?|"([^"]*)"|(\S+))
    

    regex demo 细节

    • ([^\s=]+) -组1:除空格和空格外的一个或多个字符 = 查尔斯
    • = = 签名
    • (?|"([^"]*)"|(\S+)) -分支重置组:
      • "([^"]*)" " " 捕获到第1组,然后 "
      • | -或
      • (\S+) -第2组:任意一个或多个非空白字符

    PHP demo

    $sc = '[csvtohtml_create include_rows="1-10" 
    debug_mode="no" source_type="guess" path="largecsv" 
    source_files="test?output=csv"  csv_delimiter="," ]';
    if (preg_match_all('~([^\s=]+)=(?|"([^"]*)"|(\S+))~', $sc, $ms)) {
        print_r(array_combine($ms[1],$ms[2]));
    }
    

    Array
    (
        [include_rows] => 1-10
        [debug_mode] => no
        [source_type] => guess
        [path] => largecsv
        [source_files] => test?output=csv
        [csv_delimiter] => ,
    )
    
        3
  •  0
  •   AbraCadaver    3 年前

    可能更容易找到匹配项。然后你可以做任何事。我将其转换为查询字符串并解析为数组:

    preg_match_all('/[^\s=]+="[^"]*"/', $shortcode, $result);
    parse_str(implode('&', $result[0]), $result);
    

    现在 $result 产量:

    Array
    (
        [include_rows] => "1-10"
        [debug_mode] => "no"
        [source_type] => "guess"
        [path] => "largecsv"
        [source_files] => "test?output=csv"
        [csv_delimiter] => ","
    )