PHP从字符串中获取数据

时间:2015-03-24 13:58:59

标签: php regex string

我问了几个关于这方面的问题,我尝试了很多不同的事情,但我并不完全满意。我有以下格式的大量数据

3*O#AA6160 F7 A7 P7 J7 R7 D7 I7 Y7 LHRMIA 1040 1455   *  744 0E
        B7 H0 W0 K0 M0 L0 V0 G0 S0 Q0 N0 O0 

默认情况下,您在第二行看到的空格是存在的。基本上,从该字符串我试图得到以下

$flightNumber = AA6160;
$from = LHR;
$to = MIA;
$other = 1040 1455   *  744 0E;
$seats = array(
    "F" => 7,
    "A" => 7,
    "P" => 7,
    "J" => 7,
    "R" => 7,
    "D" => 7,
    "I" => 7,
    "Y" => 7,
    "B" => 7,
    "H" => 0,
    "W" => 0,
    "K" => 0,
    "M" => 0,
    "L" => 0,
    "V" => 0,
    "G" => 0,
    "S" => 0,
    "Q" => 0,
    "O" => 0,
)

规则如下 行的开头以数字开头(在上面的例子中为3)。第二行是第一行的座位延续。如果我要发布我的完整数据,第三行以4开头,这意味着它与上面的两行无关。

航班号始终以#开头,后跟两个字母和1-4个号码。有时字母和数字之间有空格。这些是我发现的所有类型的航班号

#AA6160
#AA  57
#BA 207

第二行只包含一个座位的延续,没有别的。这是我到目前为止所提出的

while ( $elNum < $elements->length ) {

    $flightInfo = $elements->item($elNum)->nodeValue;

    if (preg_match('/^\\d/', $flightInfo) === 1) {
        if(preg_match('/(\d)+[^#]*?\#(\p{Lu}{2})\s*(\d{1,4})\b\s*([\w. ]+?)(?=\s+\p{Lu}{6})\s([A-Z]{3})([A-Z]{3})(.+)/', $flightInfo, $matches)===1){
            $row = $matches[1];
            $fltcode = $matches[2].$matches[3];
            $ffrom = $matches[5];
            $fto = $matches[6];
            $other = $matches[7];

            $this->flights[$fltcode] = array(
                "command" => $terminal_command,
                "row" => $row,
                "flightNumber" => $fltcode,
                "from" => $ffrom,
                "to" => $fto,
                "other" => $other
            );
        }
    }
    ++$elNum;
}

我正在努力的主要是座位。我不知道如何从第一行得到我需要的那些,并将它们与输出格式中第二行的那些组合,我需要它们。

我甚至不确定正则表达式是否是这里最好的选择,或者我是否应该在空格上爆炸所有内容并按照这样排序?

对此情况的任何建议表示赞赏。这是一些额外的数据

5*S#DL4386 J9 C9 D9 I9 Z9 W9 Y9 B9 LHRMIA 1235 1705   *  744 0E
        M9 S9 H9 Q9 K9 L9 U9 T9 X9 V9 
6  #VS   5 J9 C9 D9 I9 Z9 W9 S9 H9 LHRMIA 1235 1705      744 0E
        K9 Y9 B9 R9 L9 U9 M9 E9 Q9 X9 N9 O9 
7  #IB4637 F9 A9 J9 C9 D9 R9 I. W9 LHRMIA 1415 1825   *  744 0E
        Z. Y9 B9 H9 K. M. L. V. S. N. Q. O.

由于

2 个答案:

答案 0 :(得分:1)

您可以尝试更简单的方法,但我不能100%确定,这涵盖了您需要的一切。

function yourFunction($input) {
    // get the individual words, meaning split on whitespace
    $words = preg_split('/\s+/', $input);
    // filter the words the best we can
    $valuableInput = array_filter($words, function($word) {
        $chars = str_split($word); 
        return count($chars) == 2 && is_int($chars[1]);
    });

    // Create the mapping between the characters and the numbers
    $output = array();
    foreach ($valuableInput as $word) {
        $chars = str_split($word);
        $output[$chars[0]] = $chars[1]; 
    }
    return $output;
}

答案 1 :(得分:1)

使用XMLReader而不是DOMDocument进行xml解析的示例,因为它更快并且使用更少的内存。模式设计为​​更具可读性(使用自由间距模式和命名捕获)和高效(使用锚点,没有无用的unicode字符类,如\p{Lu},前瞻或未使用的捕获组)。

$xml = <<<EOD
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:terminal="http://test.com/terminal">
    <terminal:Text>1  #AY5767 F9 A9 P. J9 C9 D9 I9 Y9 LHRMIA 0945 1410   *  777 0E</terminal:Text>
    <terminal:Text>        B9 H9 K9 M9 L9 V9 S9 N9 Q9 O9 G9 </terminal:Text>

    <otherthings>blah blah blah</otherthings>

    <terminal:Text>2  #AY5768 F9 A9 P. J9 C9 D9 I9 Y9 ROMMIL 0945 1410   *  777 0E</terminal:Text>
    <terminal:Text>        B9 H9 K9 M9 L9 V9 S9 N9 Q9 O9 G9 </terminal:Text>
    <terminal:Text>        E8 G8 R8 S8 T4 U2 </terminal:Text>
</root>
EOD;

$patternFirstLine = <<<EOD
~
\A
    [0-9]+ \s+
    \# (?<code1> [A-Z]{2} ) \s* (?<code2> [0-9]{1,4} ) \s+ 
    (?<seat1> [A-Z][0-9.] (?: \s+ [A-Z][0-9.] )*+ ) \s+
    (?<from> [A-Z]{3} ) (?<to> [A-Z]{3} ) \s+
    (?<other> .*\S ) \s*
\z
~x
EOD;

$patternNextLines = <<<EOD
~
\A \s*
    (?<seatN> [A-Z][0-9.] (?: \s+ [A-Z][0-9.] )*+ )
\s* \z
~x
EOD;

$parser = new XMLReader();

$parser->xml($xml);

$temp = false;
$results = [];

while($parser->read()) {
    while ($parser->name === 'terminal:Text') {
        if (preg_match($patternFirstLine, $parser->readInnerXML(), $m)) {
            if ($temp) $results[] = $temp;

            $temp = [
                "flightNumber" => $m['code1'] . $m['code2'],
                "from"         => $m['from'],
                "to"           => $m['to'],
                "seats"        => $m['seat1'],
                "other"        => $m['other']
            ];
        } elseif ($temp && preg_match($patternNextLines, $parser->readInnerXML(), $m))
            $temp['seats'] .= ' ' . $m['seatN'];
        else
            $temp = false;

        $parser->next('Text');

    }
}

if ($temp) $results[] = $temp;

$results = array_map(function ($i) {
    $seats = explode(' ',$i['seats']);
    $i['seats'] = [];
    foreach ($seats as $seat)
        $i['seats'][$seat[0]] = $seat[1];

    return $i;
}, $results);

print_r($results);

注意:在此示例中,我使用XMLReader::xml()加载xml内容,但XMLReader的主要兴趣之一是将XMLReader::open方法与xml uri一起使用。< / p>