Regular Expression, preg_match() and storage in an array

Asked

Viewed 308 times

1

Hello. I have a .txt (Pastebin) which contains the log of the connected clients on a server openvpn and the format of each of the lines is the below:

CLIENT_LIST orion-01889596000195    177.43.212.110:28763    172.16.191.145  872199  860412  Wed May 25 07:22:52 2016    1464171772  UNDEF

I’m using the function preg_match() to store each result in a position of an array. I made the code in two ways.

First form


$log = "log.txt";
$handle = fopen($log, "r");

$inclients = false;
$cdata = array();

while (!feof($handle))
{
 $line = fgets($handle, 4096);

 if (substr($line, 0, 11) == "CLIENT_LIST")
 {
  $inclients = true;
 }
 if ($inclients)
 {
  preg_match("/\w+-\d{14}/", $line, $cdata);
  preg_match("/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\:[0-9]+/", $line, $cdata[1]);
  preg_match("/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/", $line, $cdata[2]);
  preg_match("/\s+[0-9]+/", $line, $cdata[3]);
 return var_dump($cdata[0], $cdata[1], $cdata[2], $cdata[3]);
 }
}

Second form


if ($inclients)
{
 preg_match("/\w+-\d{14}\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\:[0-9]+\s[0-9]+\. [0-9]+\.[0-9]+\.[0-9]+\s+[0-9]+\s+[0-9]+/", $line, $cdata);
 var_dump($cdata);
}

Problems I found in the first form: the name (Orion-01889596000195) and the first ip (177.43.212.110:28763) managed to store in $cdata[0] and $cdata[1] but when storing the 2nd ip (172.16.191.145) in $cdata[3] it returns to take the 1st ip but without the numbering after ":". And the other data I need to store is: 872199, 860412 and 1464171772 I couldn’t get to them.

Problems I found in the second form: I believe it was stored in $cdata[0] the following information: array(1) { [0]=> string(70) "orion-01889596000195 177.43.212.110:28763 172.16.191.145 872199 860412" } and so I don’t know how to get each information separately. Although I managed to capture the result 860412 I couldn’t move between Wed May 25 07:22:52 2016 until you get into 1464171772.

I appreciate anyone who can help me!

  • I think it would be better to separate by lines and then apply rules line by line. I’ll test it later and put an answer in if no one has solved it yet. What worries me is that you have a few lines with IP after the UNDEF, it breaks the pattern...

  • Those IP lines after the UNDEF would be like this? CLIENT_LIST UNDEF 201.14.8.164:1134 42 54 Wed May 25 15:05:07 2016 1464199507 UNDEF

  • If yes, this UNDEF at the beginning is a bug of the Open VPN server itself when it generates the log... it cannot identify the key (for example: orion-01889596000195) then he registered as UNDEF

  • Yes, exact. Ok, that means that all UNDEF must be empty strings for example?

  • Yes. My intention is to add this information to a database and then display it on a web page. As an example, log lines 3 and 4: ;CLIENT_LIST databits-13031005000123 187.17.235.203:50515 172.16.136.217 459833 409771 Wed May 25 06:09:01 2016 1464167341 UNDEF
CLIENT_LIST UNDEF 201.14.8.164:1134 42 54 Wed May 25 15:05:07 2016 1464199507 UNDEF In the third line would appear databits-13031005000123 etc etc etc E in the fourth line string-vazia etc etc etc

  • Okay, try this then: https://ideone.com/T9IIJy

  • @Sergio worked perfectly! I changed your first code and also managed to make it work perfectly. I appreciate immensely dear!

  • Great, I’ll add answer then to be complete and useful to others.

Show 3 more comments

1 answer

0


Seeing your Pastebin I see that the fields are separated by tabs, and as you mentioned UNDEF is at the bottom a null value, Undefined that can be converted to an empty string. So you can do it like this:

function processador($str){
    $partes = preg_split("/\t/", trim($str));
    $data = array_slice($partes, 1); 
    return array_map("filtro", $data);
}
function filtro($str){
    return str_replace("UNDEF", "", $str);
}

$linhas = array_filter(explode("\n", $string));
$resultado = array_map("processador", $linhas);

echo var_dump($resultado);

ideone: https://ideone.com/b3LFzS

Browser other questions tagged

You are not signed in. Login or sign up in order to post.