2008-10-03 9 views

Répondre

35
  • Aucune évasion:

    /([^=,]*)=("[^"]*"|[^,"]*)/ 
    
  • évasion Guillemet pour les deux clés et la valeur:

    /((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/ 
    
    key=value,"key with "" in it"="value with "" in it",key=value" "with" "spaces 
    
  • Backs échappement d'une chaîne cil:

    /([^=,]*)=("(?:\\.|[^"\\]+)*"|[^,"]*)/ 
    
    key=value,key="value",key="val\"ue" 
    
  • évasion backslash complète:

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

Edit: Ajouté alternatives s'échappent.

Édition2: Ajout d'une autre alternative d'échappement.

Vous devez nettoyer les clés/valeurs en supprimant les caractères d'échappement et les guillemets environnants.

+0

Cela fonctionne pour mon scénario simple! Cependant, il pourrait être bon pour lui de soutenir en incluant une citation dans la valeur en l'échappant, double ("") ou avec une barre oblique inverse (\ ") –

+0

pouvez-vous s'il vous plaît m'aider? J'ai besoin de quelque chose de similaire : //stackoverflow.com/questions/6099891/json-text-split-reg-expression-or-parser – Val

+0

ce qui est regex pour key = value & key = valeur où la clé ou la valeur peut être nulle, la clé et la valeur peuvent être n'importe quoi – virsha

2

Bonne réponse de MizardX. Négligences mineures - il ne permet pas d'espaces autour des noms etc (ce qui peut ne pas avoir d'importance), et il collecte les guillemets ainsi que la valeur citée (qui peut aussi ne pas importer), et il n'a pas de mécanisme d'échappement des guillemets doubles dans la valeur entre guillemets (ce qui, une fois de plus, peut ne pas avoir d'importance). Tel qu'écrit, le modèle fonctionne avec la plupart des systèmes d'expression régulière étendus. La fixation des déformations nécessiterait probablement une descente dans, disons, Perl. Cette version utilise doublé guillemets pour échapper - d'où a = « a » « b » génère une valeur de champ « une « » b » (ce qui est pas parfait, mais il pourrait être fixé par la suite assez facilement):

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

En outre, vous devrez utiliser $ 2 ou $ 3 pour collecter la valeur, alors qu'avec la réponse de MizardX, vous utilisez simplement $ 2. Donc, ce n'est pas aussi facile ou sympa, mais cela couvre quelques cas limites. Si la réponse la plus simple est adéquate, utilisez-la.

script Test:

#!/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//; 
    } 
} 

Cette Witters au sujet soit 2 $ ou 3 $ étant non défini - avec précision.

0

Voici comment je le ferais si vous pouvez utiliser Perl 5.10. Les éléments seraient accessibles via %+.

perlretut a été très utile pour créer cette réponse.

Questions connexes