tengo esta cadena:
$shortcode = '[csvtohtml_create include_rows="1-10" debug_mode="no" source_type="guess" path="largecsv" source_files="test?output=csv" csv_delimiter="," ]'Quiero recuperar atributos y sus valores, incluso sus signos iguales o espacios entre comillas.
Esta pregunta se basa en esta pregunta: ¿Cómo explotar una cadena pero no entre comillas en php?
tengo este codigo:
$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 );Obtengo este resultado: (source_files sin salida = csv)
Array attrs "include_rows" => "1-10" "debug_mode" => "no" "source_type" => "guess" "path" => "largecsv" "source_files" => "test.csv?output" "csv_delimiter" => ","El resultado que quiero es:
Array attrs "include_rows" => "1-10" "debug_mode" => "no" "source_type" => "guess" "path" => "largecsv" "source_files" => "test.csv?output=csv" "csv_delimiter" => ","etc...
Supongo que debería poner el signo igual (¿o es ?=) en algún lugar aquí, pero la expresión regular no es mi fuerte...
$args = preg_split('/"[^"]+"(*SKIP)(*F)|\h+/', $shortcode);Podría ser más fácil conseguir los fósforos. Entonces puedes hacer lo que sea. Lo convierto en una cadena de consulta y lo analizo en una matriz:
preg_match_all('/[^\s=]+="[^"]*"/', $shortcode, $result); parse_str(implode('&', $result[0]), $result); Ahora $result produce:
Array ( [include_rows] => "1-10" [debug_mode] => "no" [source_type] => "guess" [path] => "largecsv" [source_files] => "test?output=csv" [csv_delimiter] => "," ) Para deshacerse de las comillas, analícelo como configuración ini :
$result = parse_ini_string(implode("\n", $result[0]));Rendimientos:
Array ( [include_rows] => 1-10 [debug_mode] => no [source_type] => guess [path] => largecsv [source_files] => test?output=csv [csv_delimiter] => , )Estabas en el camino correcto con la explosión del signo igual. Esta implementación hace array_shift para obtener la clave, luego implodes el resto de la matriz.
<?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);Resultados en
Array ( [include_rows] => 1-10 [debug_mode] => no [source_type] => guess [path] => largecsv [source_files] => test?output=csv [csv_delimiter] => , )Puede hacer coincidir los nombres de los atributos y sus valores usando
([^\s=]+)=(?|"([^"]*)"|(\S+))Vea la demostración de expresiones regulares . Detalles :
([^\s=]+) - Grupo 1: uno o más caracteres que no sean espacios en blanco y = caracteres= - un signo =(?|"([^"]*)"|(\S+)) - Grupo de restablecimiento de rama:"([^"]*)" - " , luego cualquier cero o más caracteres que no sean " capturados en el Grupo 1, y luego un "| - o(\S+) - Grupo 2: uno o más caracteres que no sean espacios en blancoVea la demostración de PHP :
$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])); }Producción:
Array ( [include_rows] => 1-10 [debug_mode] => no [source_type] => guess [path] => largecsv [source_files] => test?output=csv [csv_delimiter] => , )