解析RIPE分配RegEx

时间:2013-05-17 20:45:17

标签: php regex ip-address

我正在处理需要将RIPE分配数据库(ftp://ftp.ripe.net/ripe/stats/membership/alloclist.txt)解析为数据库的项目。

我需要抓住每一个成员,所以我需要它来匹配xx之间的所有内容。和\ n \ nxx。其中x是任何小写字母。

以下是该文件的几行:

ad.andorpac
    Servei de Telecomunicacions d'Andorra 

    19960627    194.158.64.0/19 ALLOCATED PA
    20050104    85.94.160.0/19  ALLOCATED PA
    20061117    91.187.64.0/19  ALLOCATED PA
    20091124    109.111.96.0/19 ALLOCATED PA
    20120925    185.4.52.0/22   ALLOCATED PA
    20110722    2a02:8060::/31

ae.absl-me
    Asia Broadcast Satellite Ltd (Middle East) 

    20110321    31.47.88.0/21   ALLOCATED PA

ae.adac
    Abu Dhabi Airports Company PJSC 

    20120402    37.218.224.0/21 ALLOCATED PA

我不是RegEx专家,任何人都可以提供这些表达吗?

2 个答案:

答案 0 :(得分:1)

你不需要一个非常详细的正则表达式来解析它。您可以按分隔符拆分,然后解析每个条目:

// $string contains the text
$entries = explode("\n\n", $string);
for($i=0; $i < sizeof($entries); $i+=2){
    parse_header($entries[$i]));
    parse_entries($entries[$i+1]);
}

“标题”就像“ad.andorpac \ nServei de Telecomunicacions(...)”所以它应该很容易解析。要解析这些条目,可以用“\ n”拆分它们,然后用正则表达式处理它们,用空格分割字段:

function parse_entry($entries){
    $strings = explode("\n", $entries);
    foreach($strings as $s){
        preg_match("/(?P<number>\d+)\s+(?P<addr>[\d\.\/]+)\s+(?P<str1>\w+)\s+(?P<str2>\w+)/",   
            $s, $result);
    // You can then access then the results
    echo $results["addr"]; // prints "185.4.52.0/22"
    }       
}

这不是一个完整的答案,但应该解决你的大部分问题。您可能还需要使用trim函数来删除匹配字符串开头/结尾的空格。

修改

正则表达式的快速解释:

(?P<number>\d+) => matches one or more digits, and stores them in the "number" index
\s+ => matches one or more spaces and ignores them
(?P<addr>[\d\.\/]+) => matches the network address (one or more digits, dots or slashes)
\s+ => same
(?P<str1>\w+) => matches the first string ("ALLOCATED")
\s+ =>
(?P<str2>\w+) => matches the 2nd string

答案 1 :(得分:1)

类似的东西:

 preg_match_all("/[a-z]{2}\..*?\n\n[a-z]{2}\./s", $text, $matches)

应该工作。

这假设您对问题的描述是准确的!如果不是,你可以期待这个正则表达式非常脆弱。

(即:发生\n\n[a-z]{2}\.的不良实例,您希望每个匹配中包含下一个条目的前3个字符,您的记录之间将始终存在两个新行,它们将相邻,没有任何其他包括任何空格等之间的字符。)。

好吧,我猜你不会真的想要结束“xx”。作为匹配的一部分,所以替代方案是使用前瞻,例如:

     preg_match_all("/[a-z]{2}\..*?\n\n(?=[a-z]{2}\.)/s", $text, $matches)