2010-12-11 25 views
0

Je fais correspondre les conditions générales à partir d'une instruction template if. Le problème réside dans l'analyse des chaînes avant de casser l'énoncé conditionnel dans ses conditions individuelles. Je remplace les conditions de chaîne par des espaces réservés avant la rupture des conditions afin que les chaînes n'interfèrent pas avec la correspondance de modèle de rupture.Regex: faire correspondre les chaînes sans rompre la chaîne de correspondance en faisant correspondre une citation échappée au milieu de la chaîne.

Le code ci-dessous fait son travail bien.

// remove quoted strings from conditional elements as will conditional tokenising below 
if (preg_match_all('/([\"\'])([^\\1]*?)\\1/s', $conditions, $string_matches)) 
{ 
    $uid = uniqid(time().'_'); 
    $strings = array(
      'id' => $uid, 
      'matches' => array() 
     ); 
    $replacements = array(); 
    foreach($string_matches[0] as $key=>$match) 
    { 
     $match_id = '#'.$uid.md5($match); 
     $replacements[$match] = $match_id; 
     $strings['matches'][$match_id] = array(
       'match' => $match, 
       'content' => $string_matches[2][$key], 
      ); 
    } 
    $conditions = str_replace(array_keys($replacements), array_values($replacements), $conditions); 
} 

Il correspond à la suivante grande

boolean_arg1 && arg2 !== 'testing multi quotes' && arg3 === "test & yup" -or- 
boolean_arg1 && arg2 !== 'testing "multi" quotes' && arg3 === "test & yup" 

me donner

boolean_arg1 && arg2 !== #1292059008_4d0341809c0f74062e5ac5086fb24f8e8383a137a5a5e && arg3 === #1292059008_4d0341809c0f7d4820850f1f6e06677e741be556352e3 
boolean_arg1 && arg2 !== #1292059102_4d0341de3f5196213c34e77a2cfbb11f867f9ed57c85f && arg3 === #1292059102_4d0341de3f519d4820850f1f6e06677e741be556352e3 

Cependant l'introduction se sont échappés des citations dans la chaîne, rompt la correspondance de motif à la chaîne échappée.

boolean_arg1 && arg2 !== 'testing "multi" \'quotes' && arg3 === "test && yup" 

donne

boolean_arg1 && arg2 !== #1292059161_4d03421974c3166a7cae87ddc1002905892eff6453bd4quotes' && arg3 === #1292059161_4d03421974c31d4820850f1f6e06677e741be556352e3 

(citations de communication) après le premier remplacement.

Je ne suis pas très bon pour faire des recherches et autres. Je me demandais s'il existe une solution simple pour convertir la regex dans le code ci-dessus à celle qui correspond à des chaînes complètes avec des guillemets échappés en eux?

Répondre

1

Utilisez un modèle qui reflète les séquences d'échappement comme:

/"(?:[^"\\]*|\\["\\])*"|'(?:[^'\\]*|\\['\\])*'/ 

Avec ce que les séquences d'échappement de \\ et \" ou \' respectivement sont connus. Vous pouvez les développer en changeant le ["\\]/['\\].

+0

Cette regex génère une erreur de compilation? Je pensais que c'était le?: [Mais l'avoir échappé ça ne marche pas. Pas certain de pourquoi. – buggedcom

+0

@buggedcom: Assurez-vous d'échapper correctement '' 'et guillemets dans votre chaîne. – Gumbo