Регулярные выражения/разбор вывода dig/извлечение текста из двойных кавычек

Мне нужна помощь в определении некоторых регулярных выражений. Я запускаю команду dig, и мне нужно использовать ее вывод. Мне нужно разобрать его и аккуратно упорядочить в виде массива с помощью php.

dig выдает что-то вроде этого:

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"

Я хочу получить это:

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

Мне просто нужно содержимое внутри двойных кавычек. Я могу разобрать вывод dig построчно, но я думаю, что было бы быстрее, если бы я просто запускал сопоставление с шаблоном регулярного выражения для всего этого...

Мысли?


person Steve    schedule 24.06.2009    source источник


Ответы (4)


Это приближается к одной строке

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

print_r( $matches );

однако из-за того, как работают функции preg_match*, полное совпадение включается в индекс 0 каждой группы совпадений. Вы могли бы исправить это, если бы действительно хотели.

array_walk( $matches, create_function( '&$array', 'array_shift( $array );return $array;' ) );
person Peter Bailey    schedule 24.06.2009
comment
Спасибо, Питер - ваше решение избавилось от двойных кавычек. Это то, что мне было нужно! - person Steve; 25.06.2009

Я не уверен в регулярных выражениях PHP, но в Perl RE будет простым:

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

Это имеет некоторые ограничения, а именно:

  • Это не работает, если текст в кавычках может быть заключен в кавычки (например, \")
  • Он жестко запрограммирован для поддержки только четырех значений в кавычках.
person Jamie Love    schedule 24.06.2009

Код:

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

Выход:

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"
        )

)
person John Kugelman    schedule 24.06.2009
comment
Привет, Джон! Я основал свое окончательное решение на вашем и Питере (ниже). Комбинация того и другого сработала для меня. Спасибо за оперативность и внимание к деталям!! - person Steve; 25.06.2009

Совершенно не то, что вы просили, но оно работает, может использоваться для строк с любым количеством кавычек и имеет то преимущество, что оно более читабельно, чем ваше обычное регулярное выражение (за счет большего количества кода)

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);  
person Alan Storm    schedule 24.06.2009