Expresiones regulares / salida de digitación de análisis / extracción de texto de comillas dobles

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

  •  22-07-2019
  •  | 
  •  

Pregunta

Necesito ayuda para descubrir algunas expresiones regulares. Estoy ejecutando el comando de excavación y necesito usar su salida. Necesito analizarlo y ordenarlo ordenadamente como una matriz usando php.

dig produce algo como esto:

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"

Quiero obtener esto:

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

Solo necesito el contenido dentro de las comillas dobles. puedo analizar la salida de excavación línea por línea, pero creo que sería más rápido si solo ejecutara la coincidencia del patrón de expresiones regulares en todo ...

¿Pensamientos?

¿Fue útil?

Solución

Esto se acerca con una sola línea

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

print_r( $matches );

sin embargo, debido a cómo funcionan las funciones preg_match *, la coincidencia completa se incluye en el índice 0 de cada grupo de coincidencia. Podrías arreglar esto si realmente quisieras.

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

Otros consejos

No estoy seguro acerca de las expresiones regulares de PHP, pero en Perl el RE sería 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

Esto tiene algunas limitaciones, a saber:

  • No funciona si el texto en las comillas puede tener comillas escapadas (por ejemplo, \ " )
  • Está codificado para admitir solo cuatro valores citados.

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);
?>

Salida:

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 no es lo que solicitó, pero funciona, podría usarse para cadenas con cualquier cantidad de comillas y tiene el beneficio de ser más legible que su expresión regular promedio (a expensas de mucho más 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top