i have a text and i want convert it to array by exclude but i cant get true array
# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER 0 10.40.47.48 216.58.205.211 12 822 2 1 10.40.47.48 102.132.97.21 66 9390 2 2 184.106.10.77 10.40.47.252 10 1819 1 3 10.40.47.252 104.27.155.225 1 41 1 4 10.40.47.252 144.76.103.6 5 878 1 5 102.132.97.35 10.40.47.252 11 1159 1 6 10.40.47.252 52.169.53.217 1 397 1 7 104.27.155.225 10.40.47.252 1 52 1
and i want result like this
Array
(
[0] => Array
(
[.id] => *0
[src-address] => 10.40.47.50
[dst-address] => 185.144.157.141
[packets] => 6
[bytes] => 1349
)
[1] => Array
(
[.id] => *1
[src-address] => 195.122.177.151
[dst-address] => 10.40.47.48
[packets] => 4
[bytes] => 174
[dst-user] => 2
)
....
i try this but it is wrong
$arr = exclude(" ",$text);
edit :
i can get text by another way
0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" 1 src-address=10.40.47.48 dst-address=172.217.19.150 packets=11 bytes=789 src-user="2" 2 src-address=184.106.10.77 dst-address=10.40.47.252 packets=26 bytes=5450 dst-user="1"
As I mentioned in the comments, one way would be to first explode your input by " " (space). You loop through each element/row of the resulting array. Then you explode each of those by = (equals sign). If the result of that explode is a single-element array, you know you should start a new row and create a key-value pair using your special .id key. If the count of the result is two, take the first part and make it the key of a new key-value pair in the current row, and take the second part and make it the value of that key-value pair.
There's a bit of a wrinkle in the fact that some of your source values are quoted, but you seem to want them not quoted in the result. To handle that we do a lose equality check on the value to see if it is the same when converted to an integer or not. If it is, then we convert it to remove the quotes.
$inputText = '0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" 1 src-address=10.40.47.48 dst-address=172.217.19.150 packets=11 bytes=789 src-user="2" 2 src-address=184.106.10.77 dst-address=10.40.47.252 packets=26 bytes=5450 dst-user="1"';
$result = array();
$spaceParts = explode(" ", $inputText);
foreach($spaceParts as $part)
{
$subParts = explode("=", $part);
if(count($subParts) == 1)
{
$resultIndex = (isset($resultIndex) ? $resultIndex+1 : 0);
$result[$resultIndex] = array(".id" => "*".$part);
}
else if(count($subParts) == 2)
{
$result[$resultIndex][$subParts[0]] = ((int)$subParts[1] == $subParts[1] ? (int)$subParts[1] : $subParts[1]);
}
else
{
// unexpected, handle however you want
}
}
print_r($result);
DEMO
Try reading the string in using str_getcsv replacing the delimiter with whatever the string is delimited by.
var_dump(str_getcsv($input, ","));
Note the manual states that the delimiter must be one char long. If wanting a tab or multiple spaces you will need to look into the answer:
str_getcsv on a tab-separated file
str-getcsv php manual
Here is something that could work but I would recoment using the csv methods instead to read the data in . And it is unclear how your data should be actually mapped to header.
$header = "# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER ";
$input = "# SRC-ADDRESS DST-ADDRESS PACKETS BYTES SRC-USER DST-USER 0 10.40.47.48 216.58.205.211 12 822 2 1 10.40.47.48 102.132.97.21 66 9390 2 2 184.106.10.77 10.40.47.252 10 1819 1 3 10.40.47.252 104.27.155.225 1 41 1 4 10.40.47.252 144.76.103.6 5 878 1 5 102.132.97.35 10.40.47.252 11 1159 1 6 10.40.47.252 52.169.53.217 1 397 1 7 104.27.155.225 10.40.47.252 1 52 1 ";
$string = str_replace($header, "", $input );
$delimiter = " ";
$columns = 6;
$splitData = explode($delimiter, $string);
$result = [];
$i= 0;
foreach ($splitData as $key => $value) {
$result[$i][] = $value;
if (($key+1) % $columns == 0 ){
$i++;
}
}
var_dump($result);
Using the second example with the 0 src-address=108.177.15.188 dst-address=10.40.47.252 packets=1 bytes=52 dst-user="1" format, there are 6 entries:
$result = array_map(function($v) {
parse_str("id=".implode("&", $v), $output);
return $output;
}, array_chunk(explode(' ', $text), 6));
Explode the array on spaces
Chunk the array into 6 entries per element
Map to a function that implodes each array on & and parse it as a query string
Related
If I have a string as : 10 20 3 4 15 6
How can I convert it to individual numbers and store it in a array?
PHP is very clever when dealing with types of variables. You don't need it to be an integer, it can be a string of numbers, and PHP would still treat it as integers when performing operations on them.
If you want to have each element be the numbers separated by spaces, you simply do
$array = explode(" ", "10 20 3 4 15 6");
The output of $array would then be
Array (
[0] => 10
[1] => 20
[2] => 3
[3] => 4
[4] => 15
[6] => 6
)
Live demo
$str = "10 20 3 4 15 6";
$arr = str_split($str);
$intArr = array_map('intval', $arr);
Might be a better way of doing it but the above should do the work.
The array is like this
$a = array(1,2,3,4,5,6,7,8);
After that in each iteration the 3rd element should be removed until it reaches to a single element
the iteration will be something like this
index:0 1 2 3 4 5 6 7
value:1 2 3 4 5 6 7 8
this is the normal one
index:0 1 2 3 4 5 6 7
value:1 2 4 5 7 8
here 3 and 6 removed as they came out as the 3rd elements
then after 6 is removed it should count 7 and 8 as 1st and 2nd and go to value 1 which makes 1 as the 3rd element.This continues until there is only one element remaining.
output
12345678
1245678
124578
24578
2478
478
47
7
7 is the remaining element
here is the code, hope it helps.
<?php
$array = [1,2, 3,4,5,6,7,8];
function removeAtNth($array, $nth)
{
$step = $nth - 1; //gaps between operations
$benchmark = 0;
while(isset($array[1]))
{
$benchmark += $step;
$benchmark = $benchmark > count($array) -1 ? $benchmark % count($array) : $benchmark;
echo $benchmark."\n";
unset($array[$benchmark]);
$array = array_values($array);
echo implode('', $array)."\n";
}
}
removeAtNth($array, 3);
result:
kris-roofe#krisroofe-Rev-station:~$ php test.php
1245678
124578
24578
2478
478
47
7
Your looking for array_chunk()
$a = array(1,2,3,4,5,6,7,8);
$thirds = array_chunk($a, 3);
$thirds now is like:
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
[1] => 8
)
)
Then just loop through the $thirds array and array_pop() to grab the last value.
However, I'm not sure why you're looking to get 7 at the end and not 8. Can you explain?
Example :
$_fp = fopen("file.txt", "r");
/* STDIN = "4 7 6 24 1"; */ <== user input
$input[] = fgets($_fp);
print_r($input);
OUTPUT :
Array
(
[0] => 4 7 6 24 1
)
Desired OUTPUT :
Array
(
[0] => 4
[1] => 7
[2] => 6
[3] => 24
[4] => 1
)
Is there any method to remove spaces from integer input after entering each to an array?
In a way to avoid having the whole input as one single line.
i used $input[] = explode(' ', trim(fgets($_fp))); now when there is second line it only puts the first line of the STDIN i need to read all lines and put them into the input variable
while($f = fgets(STDIN)){ echo "line: $f"; } is great use here
it is fine for echoing all lines but cant assign each line to a variable or array yet.. not sure if i should array_push() since i need 2 lines as variables and rest as arrays..
use trim remove the "\n" of the line, the use explode to convert it to array.
Live Demo
$input = explode(' ', trim(fgets($_fp)));
if you has more lines, use below:
$input[] = explode(' ', trim(fgets($_fp)));
Even we can try preg_match_all with regx also give same result with all cases like what if you have double space or any text between the interger strings
$string = "4 7 6 24 1";
$string = "4 test df 7 6 24 1";
$string = "4 7 6 24 1";
preg_match_all('!\d+!', $string, $matches);
print_r($matches);
I am trying to parse a file using php but I am not sure of the best way to do it. The file consists of stuff like:
saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1
What I'm trying to do is split it up and populate a hash map, so..
$inventory["saturn+5"] = "57";
$inventory["space+shuttle"] = "34";
and so on.
I don't know how to tackle this.
I am trying to write a bit of regex to process the file to separate out the fields but I'm not having much luck and was wondering if I should try using a different approach using split() or explode().
Here's my approach using regular expression.
$data = 'saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1';
$inventory = array();
preg_match_all('/(\S+) (\S+)/', $data, $matches);
foreach ($matches[1] as $index => $match) {
$inventory[$match] = $matches[2][$index];
}
print_r($inventory);
Output
Array
(
[saturn+5] => 57
[space+shuttle] => 34
[gemini] => 12
[mercury] => 2
[soyuz+tm] => 1
)
my crude approach:
<?php
echo '<pre>';
$str="saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1";
//break it on space
$e=explode(' ',$str);
//reindex array to start from 1
array_unshift($e, "phoney");
unset($e[0]);
print_r($e);
$inventory=array();
foreach ($e as $k=>$v){
//detects odd key
if(($k+2)%2==1) {
$inventory[$v]= $e[$k+1];
}
}
print_r($inventory);
demo: http://codepad.viper-7.com/PN6K8m
output:
Array
(
[saturn+5] => 57
[space+shuttle] => 34
[gemini] => 12
[mercury] => 2
[soyuz+tm] => 1
)
It's actually quite trivial with a regex:
preg_match_all("/ ([\w+]+) \s (\d+) /x", $string, $m);
$assoc = array_combine($m[1], $m[2]);
You're just looking for a combination of alphanumeric characters \w and optional + signs, then a space, then a \d decimal.
array_combine will give you the associative array.
If it's always in that order, this will work:
<?
$foo = 'saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1';
$foo_array = preg_split('/\s+/', $foo);
$hash = array();
for ($i = 0; $i < count($foo_array); $i++){
$i % 2 ? null : $hash[$foo_array[$i]] = $foo_array[++$i];
}
print_r($hash);
?>
Output:
php foo.php
Array
(
[saturn+5] => 57
[space+shuttle] => 34
[gemini] => 12
[mercury] => 2
[soyuz+tm] => 1
)
I have data which I wish to be pasted into a textbox, it will be in the form E.G
Ryu Aiter D78:21:87:13 177 /177 1 / 6
Ryu Chronos D78:21:26:21 182 /182 0 / 6
Ryu Hermes D78:21:26:22 201 /201 0 / 6
Ryu Hefaistos D78:31:75:10 136 /136 1 / 2
Ryu Krotos D78:84:96:11 170 /170 1 / 6
Ryu Heros D78:65:51:31 175 /175 2 / 5
Ryu Arachnos D78:13:84:11 185 /185 0 / 5
its splits up like this
Base(max 16 chars)
Location(staring D , 12 chars)
econ/max econ (int/int)
used/Total(int/int)
What i wish to do is create a loop for each Row of text,
and then inside that loop chop out each part of the row into variables for each component.
as far as ideas on separating it i know that the : symbol is banned from names and bases.
so if i find the first ":" then step back 2 and take the next 12 chars that is my location
i know that can be done with a until loop and if(string[x]=':')
But how do i loops through rows?
And how can i separate the rest of the data in a row?
This is what regular expressions are for :P try this out:
$lines = explode( "\r\n", $data );
$users = array();
foreach( $lines as $line )
{
$matches = array();
$user = array();
preg_match( "/([^ ]+) ([^ ]+) ((?:[A-Z])(?:[0-9]+:){3}[0-9]+) ([0-9]+) \/([0-9]+) ([0-9]+) \/ ([0-9]+)/", $line, $matches );
list(,$user['name'],$user['base'],$user['location'],$user['econ'],$user['maxecon'],$user['used'],$user['total']) = $matches;
$users[] = $user;
}
You will have an array called users which contains a series of associative arrays with the components. Like below...
Array
(
[0] => Array
(
[total] => 6
[used] => 1
[maxecon] => 177
[econ] => 177
[location] => D78:21:87:13
[base] => Aiter
[name] => Ryu
)
[1] => Array
(
[total] => 6
[used] => 0
[maxecon] => 182
[econ] => 182
[location] => D78:21:26:21
[base] => Chronos
[name] => Ryu
)
etc, etc...
EDIT: I made a lot of assumptions about the data as you haven't given many details, if you need further help with the expression let me know.
UPDATE AS PER YOUR COMMENT:
Line 182: $name = htmlspecialchars(mysql_real_escape_string($_POST['name']));
Line 188: $tecon = htmlspecialchars(mysql_real_escape_string($user['econ']));
You should turn on display_errors as they were simple syntax errors that could easily be debugged.
Can you just use explode and gradually break it down?
eg.
explode the entry into seperate lines at '\n'
then explode each line into 2, everything before the 1st ':', and everything after
explode the 1st part into pieces using each 'space' to give you Name, Base, Location
explode the 2nd part using 'space', ':' or '/' to give you econ/max econ and used/Total
if(preg_match_all('/^([a-z]{1,16})\s+([a-z]{1,16})\s+(D\d+):(\d+):(\d+):(\d+)\s+(\d+)\s+\/(\d+)\s+(\d+)\s+\/\s+(\d+)$/mi', $yourinputgoeshere, $match) {
print_r($match);
}
This should, untested, get everything into a large array, separated. Untested
Extending the same idea i am trying to use preg match for a single line on another page.
i use the code
$data = $_POST['list'];
$matches = array();
$user = array();
preg_match( "/(.+?) ((?:[A-Z])(?:[0-9]+:){3}[0-9]+) ([0-9]+) \/([0-9]+) ([0-9]+) \/ ([0-9]+)/", $data, $matches );
list(,$user['base'],$user['location'],$user['econ'],$user['maxecon'],$user['used'],$user['total']) = $matches;
$base = $users['base'];
$location = $users['location'];
$tecon = $users['econ'];
i used echo to print out £data and it contains the data as expected but the same code without the lines loop does not seperate the parts of my data into the array..in fact the array size of $user remains empty, what has gone wroung?