As expressões regulares / análise saída dig / texto extração de aspas duplas
Pergunta
Eu preciso de ajuda para descobrir algumas expressões regulares. Estou executando o comando dig e eu preciso usar sua saída. Eu preciso analisá-lo e fazê-lo bem organizada como uma matriz usando PHP.
dig saídas algo como isto:
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"
Eu quero conseguir isso:
Array
(
[0] => Array
(
[0] => .tkw
[1] => 1
[2] => 20090624-183342
[3] => Some text here1
)
[1] => Array
...
)
Eu só preciso o conteúdo dentro das aspas duplas. I pode analisar a linha de saída de escavação por linha, mas eu acho que seria mais rápido se eu simplesmente executar a correspondência de padrão regex em tudo isso ...
Os pensamentos?
Solução
Este se aproxima com uma única linha
preg_match_all( '/"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"/', $text, $matches, PREG_SET_ORDER );
print_r( $matches );
No entanto, becuase de como o preg_match * funções de trabalho, o jogo completo está incluído no índice 0 de cada grupo jogo. Você poderia corrigir isso, se você realmente queria.
array_walk( $matches, create_function( '&$array', 'array_shift( $array );return $array;' ) );
Outras dicas
Eu não tenho certeza sobre PHP expressões regulares, mas em Perl do RE seria simples:
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
Isto tem algumas limitações, nomeadamente:
- Não funciona se o texto nas citações pode ter citações escaparam (por exemplo
\"
) - É difícil codificadas para suportar apenas quatro valores indicados.
Código:
<?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);
?>
Output:
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" ) )
Totalmente não o que você pediu, mas ela não funciona, poderia ser usado para cordas com qualquer número de citações, e tem a vantagem de ser mais legível do que a sua expressão regular média (em detrimento da forma mais código)
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);