As expressões regulares / análise saída dig / texto extração de aspas duplas

StackOverflow https://stackoverflow.com/questions/1041199

  •  22-07-2019
  •  | 
  •  

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?

Foi útil?

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);  
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top