Last active
December 20, 2015 12:08
-
-
Save DNA/6128248 to your computer and use it in GitHub Desktop.
Process a BGP table, returning the tabulated data into an array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Código feito em PHP, Haters Gonna Hate! :P | |
* | |
* Brincadeiras a parte, foi a forma mais eficiente de resolver o | |
* problema, tenho certeza que passar a lógica pra Python pra vc vai | |
* ser fichinha! :P | |
*/ | |
// Input de dados para exemplo | |
$input = 'BGP table version is 0, local router ID is 10.0.0.2 | |
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, | |
r RIB-failure, S Stale, R Removed | |
Origin codes: i - IGP, e - EGP, ? - incomplete | |
Network Next Hop Metric LocPrf Weight Path | |
* 172.31.1.0/24 40.0.0.4 0 7678 7675 i | |
*> 10.0.0.1 0 0 7675 i | |
*> 172.31.2.0/24 0.0.0.0 0 32768 i | |
*> 172.31.3.0/24 10.0.0.1 0 7675 7677 i | |
* 40.0.0.4 0 7678 7677 i | |
* 172.31.4.0/24 10.0.0.1 0 7675 7678 i | |
*> 40.0.0.4 0 0 7678 i | |
*> 000.00.0.0/00 00.0.0.0 0 0 0 7678 0000 i | |
Total numberof prefixes 4'; | |
$block = explode("\n\n", $input); // Pega só o bloco principal a ser processado | |
$lines = explode("\n", $block[1]); // Gera um array com uma informação por linha | |
$header = array_shift($lines); // Pega a primeira linha que é o header da tabela | |
$header = str_replace('Next Hop', 'Next_Hop', $header); // POG, admito, shame on me! XP | |
/** | |
* Aqui começa a maracutaia. Essa regex pega a primeira letra precedida de um espaço. | |
* Dessa forma, consigo ter um array com todos os "headers" da tabela | |
*/ | |
$header = preg_split('/ [a-zA-Z]/', $header); | |
// No split, a primeira coluna só perdeu 1 caracter, então retiramos mais um aqui | |
$header[0] = substr($header[0], 0, -1); | |
$output = array(); | |
$regex = array(); | |
/** | |
* Aqui a gente interage com esses headers, gerando um RegEx a ser usado depois | |
* O "$column+1" acontece porquê a nossa regex anterior "comeu" os dois primeiros | |
* caracteres do nome da tabela, então temos de compensar aqui! | |
*/ | |
foreach ($header as $column) { | |
$regex[] = '(.{' . (strlen($column)+2) . '})'; | |
} | |
/** | |
* Aqui removemos o último elemento da array, e substituimos por (.+), pois ele | |
* deve seguir até o final da linha. O implode serve para transformar a array em | |
* uma string, sendo que neste nosso exemplo ela deve ficar assim: | |
* | |
* "/(.{3})(.{16})(.{19})(.{6})(.{6})(.{6})(.+)/" | |
*/ | |
array_pop($regex); | |
$regex = '/' . implode($regex) . '(.+)/'; | |
/** | |
* Agora vamos ao que interessa. Iteramos as linhas com os dados a serem procesados, | |
* aplicando a RegEx a cada linha do array. O array_shift remove o primeiro elemento | |
* desse array, que é a string completa, e depois aplicamos o comando trm() a todos | |
* os elementos, restando apenas os dados que não interessa. Se a coluna estiver | |
* vazia, o trim() vai deixar nosso elemento do array vazio. | |
*/ | |
foreach ($lines as $line) { | |
preg_match_all($regex, $line, $result, PREG_SET_ORDER); | |
array_shift($result[0]); // remove o primeiro elemento, que é a string completa | |
$result = array_map('trim', $result[0]); | |
$output[] = $result; | |
} | |
var_dump($output); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cuidado com o split para não cortar no indice errado.