0

我需要帮助找出一些正则表达式。我正在运行 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 输出,但我认为如果我只对所有它运行正则表达式模式匹配会更快......

想法?

4

4 回答 4

2

我不确定 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

这有一些限制,即:

  • \"如果引号中的文本可以有转义引号(例如),则它不起作用
  • 它被硬编码为仅支持四个引用值。
于 2009-06-24T22:02:04.140 回答
0

代码:

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

输出:

大批
(
    [0] => 数组
        (
            [0] => ".tkw" "1" "20090624-183342" "这里有一些文字1"
            [1] => ".tkw"
            [2] => "1"
            [3] => "20090624-183342"
            [4] => "这里有一些文字1"
        )

    [1] => 数组
        (
            [0] => ".tkw" "1" "20090624-183341" "这里有一些文字2"
            [1] => ".tkw"
            [2] => "1"
            [3] => "20090624-183341"
            [4] => "这里有一些文字2"
        )

)
于 2009-06-24T22:17:28.133 回答
0

这很接近单行

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;' ) );
于 2009-06-24T22:18:25.090 回答
0

完全不是您要求的,但它确实有效,可用于带有任意数量引号的字符串,并且具有比普通正则表达式更具可读性的好处(以更多代码为代价)

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);  
于 2009-06-24T23:03:05.483 回答