2008-10-03 11 views

Respuesta

35
  • No hay escape:

    /([^=,]*)=("[^"]*"|[^,"]*)/ 
    
  • doble de escape presupuesto de ambas claves y valores:

    /((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/ 
    
    key=value,"key with "" in it"="value with "" in it",key=value" "with" "spaces 
    
  • Backs las pestañas de escape cadena:

    /([^=,]*)=("(?:\\.|[^"\\]+)*"|[^,"]*)/ 
    
    key=value,key="value",key="val\"ue" 
    
  • completa barra invertida:

    /((?:\\.|[^=,]+)*)=("(?:\\.|[^"\\]+)*"|(?:\\.|[^,"\\]+)*)/ 
    
    key=value,key="value",key="val\"ue",ke\,y=val\,ue 
    

Editar: Agregado alternativas que escapan.

Edit2: Se agregó otra alternativa de escape.

Debería limpiar las claves/valores eliminando los caracteres de escape y las comillas circundantes.

+0

¡Esto funciona para mi situación simple! Sin embargo, podría ser bueno que sea compatible con incluir una cotización en el valor escapándolo, ya sea doble ("") o con una barra invertida (\ ") –

+0

¿me puede ayudar por favor? Necesito algo similar, pero más como json http : //stackoverflow.com/questions/6099891/json-text-split-reg-expression-or-parser – Val

+0

lo que es regex para clave = valor & clave = valor donde la clave o el valor pueden ser nulos, la clave y el valor pueden ser cualquier cosa – virsha

2

Buena respuesta de MizardX. Problemas menores: no permite espacios en torno a nombres, etc. (que pueden no importar), y recoge las comillas, así como el valor citado (que también puede no importar), y no tiene un mecanismo de escape para incrustar comillas dobles en el valor citado (que, una vez más, puede no importar).

Como está escrito, el patrón funciona con la mayoría de los sistemas de expresión regular extendidos. Arreglar los problemas probablemente requeriría un descenso en, digamos, Perl. Esta versión utiliza un doble comillas para escapar - por lo tanto, a = "A" "B" genera un valor de campo 'A '' B' (que no es perfecto, pero podría fijarse posteriormente con bastante facilidad):

/\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/ 

Además, tendría que usar $ 2 o $ 3 para cobrar el valor, mientras que con la respuesta de MizardX, simplemente usa $ 2. Por lo tanto, no es tan fácil o agradable, pero cubre algunos casos extremos. Si la respuesta más simple es adecuada, úselo.

escritura de la prueba:

#!/bin/perl -w 

use strict; 
my $qr = qr/\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/; 

while (<>) 
{ 
    while (m/$qr/) 
    { 
     print "1= $1, 2 = $2, 3 = $3\n"; 
     $_ =~ s/$qr//; 
    } 
} 

Este Witters sobre cualquiera de $ 2 o $ 3 es indefinido - con precisión.

0

Así es como lo haría si puede usar Perl 5.10.

 
qr/ 
    (?<key> 
    (?: 
     [^=,\\] 
    | 
     (?&escape) 
    )++ # Prevent null keys 
) 

    \s*+ 
    = 
    \s*+ 

    (?<value> 
    (?&quoted) 
    | 
    (?: 
     [^=,\s\\] 
    | 
     (?&escape) 
    )++ # Prevent null value (use quotes for that) 
) 

    (?(DEFINE) 
    (?<escape>\\.) 
    (?<quoted> 
     " 
     (?: 
      (?&escaped) 
     | 
      [^"\\] 
     )*+ 
     " 
    ) 
) 
/x 

Los elementos se puede acceder a través %+.

perlretut fue muy útil para crear esta respuesta.

Cuestiones relacionadas