2009-06-24 9 views
0

J'ai besoin d'aide pour trouver des expressions régulières. J'exécute la commande dig et j'ai besoin d'utiliser sa sortie. J'ai besoin de l'analyser et de l'ordonner comme un tableau utilisant php.Expressions régulières/parsing dig output/extraction de texte à partir de guillemets

creuser des sorties quelque chose comme ceci:

m0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183342" "Some text here1" 
m0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183341" "Some text here2" 

Je veux obtenir ceci:

Array 
(
    [0] => Array 
     (
      [0] => .tkw 
      [1] => 1 
      [2] => 20090624-183342 
      [3] => Some text here1 
     ) 
    [1] => Array 
... 
) 

J'ai juste besoin le contenu à l'intérieur des guillemets doubles. I peut analyser la sortie de creuser ligne par ligne, mais je pense qu'il serait plus rapide si je viens d'exécuter le motif regex correspondant sur tout cela ...

Pensées?

Répondre

0

Cela se rapproche avec une seule ligne

preg_match_all('/"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"/', $text, $matches, PREG_SET_ORDER); 

print_r($matches); 

cependant becuase de la façon dont les preg_match * fonctions de travail, la la correspondance complète est incluse à l'index 0 de chaque groupe de correspondance. Vous pourriez résoudre ce problème si vous le vouliez vraiment.

array_walk($matches, create_function('&$array', 'array_shift($array);return $array;')); 
+0

Merci Peter - votre solution s'est débarrassé des guillemets. C'est ce dont j'avais besoin! – Steve

2

Je ne suis pas sûr de PHP expressions régulières, mais en Perl le RE serait simple:

my $c = 0; 
print <<EOF; 
Array 
(
EOF 
foreach (<STDIN>) { 
    if (/[^"]*"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"/) { 
     print <<EOF; 
    [$c] => Array 
     (
      [0] = $1 
      [1] = $2 
      [2] = $3 
      [3] = $4 
     ) 
EOF 
     $c++; 
    } 
} 

print <<EOF; 
) 
EOF 

Cela a des limites, à savoir:

  • Il ne fonctionne pas si le texte dans les guillemets peuvent avoir échappé des guillemets (par exemple \")
  • Il est codé en dur pour prendre en charge uniquement quatre valeurs entre guillemets.
0

code:

<?php 
    $str = 'm0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183342" "Some text here1" 
m0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183341" "Some text here2"'; 

    header('Content-Type: text/plain'); 
    $matches = array(); 
    preg_match_all('/(".*").*(".*").*(".*").*(".*")/U', $str, $matches, PREG_SET_ORDER); 
    print_r($matches); 
?> 

Sortie:

 
Array 
(
    [0] => Array 
     (
      [0] => ".tkw" "1" "20090624-183342" "Some text here1" 
      [1] => ".tkw" 
      [2] => "1" 
      [3] => "20090624-183342" 
      [4] => "Some text here1" 
     ) 

    [1] => Array 
     (
      [0] => ".tkw" "1" "20090624-183341" "Some text here2" 
      [1] => ".tkw" 
      [2] => "1" 
      [3] => "20090624-183341" 
      [4] => "Some text here2" 
     ) 

) 
+0

Salut John! J'ai basé ma solution finale sur la vôtre et celle de Peter (ci-dessous). Une combinaison des deux a fonctionné pour moi. Appréciez votre rapidité d'exécution et votre attention aux détails !! – Steve

0

totalement pas ce que vous avez demandé, mais il fonctionne, pourrait être utilisé pour les chaînes avec un certain nombre de citations, et a l'avantage d'être plus lisible que l'expression régulière moyenne (au détriment de la manière plus code)

class GetQuotedText { 
    const STATE_OUTSIDE = 'STATE_OUTSIDE'; 
    const STATE_INSIDE = 'STATE_INSIDE'; 

    static private $input; 
    static private $counter; 
    static private $state; 
    static private $results; 

    static private $current; 
    static private $full; 
    static private $all; 

    static private function setInput($string) { 
     $this->input = $string; 

    } 

    static private function init($string) { 
     self::$current = array(); 
     self::$full   = array();  
     self::$input = $string; 
     self::$state = self::STATE_OUTSIDE; 
    } 


    static public function getStrings($string) { 
     self::init($string); 
     for(self::$counter=0;self::$counter<strlen(self::$input);self::$counter++){ 
      self::parse(self::$input[self::$counter]); 
     } 
     self::saveLine(); 
     return self::$all; 
    } 

    static private function parse($char) { 
     switch($char){ 
      case '"': 
       self::encounteredToken($char); 
       break;  
      case "\n": //deliberate fall through for "\n" and "\r" 
      case "\r": 
       self::encounteredToken($char); 
       break; 
      default: 
       if(self::$state == self::STATE_INSIDE) { 
        self::action($char); 
       } 
     } 
    } 

    static private function encounteredToken($token) { 
     switch($token) { 
      case '"': 
       self::swapState(); 
       break; 
      case "\n": //deliberate fall through for "\n" and "\r" 
      case "\r": 
       self::saveArray(); 
       self::saveLine(); 
       break; 
     } 
     return; 
    } 

    static private function swapState() { 
     if(self::$state == self::STATE_OUTSIDE) { 
      self::$state = self::STATE_INSIDE; 
     } 
     else { 
      self::$state = self::STATE_OUTSIDE;    
      self::saveArray(); 
     }    
    } 
    static public function saveLine() { 
     self::$all[] = self::$full; 
     self::$full = array(); 
     //reset state when line ends 
     self::$state = self::STATE_OUTSIDE; 
    } 

    static private function saveArray() { 
     if(count(self::$current) > 0) { 
      self::$full[] = implode ('',self::$current); 
      self::$current = array(); 
     } 
    } 

    static private function action($char) { 
     self::$current[] = $char; 
    } 
} 

$input = 'm0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183342" "Some text here1"' . "\n" . 
     'm0.ttw.mydomain.tel. 60  IN  TXT  ".tkw" "1" "20090624-183341" "Some text here2"'; 
$strings = GetQuotedText::getStrings($input); 
print_r($strings); 
Questions connexes