Multiple comparison and edit file - php

Here is my $file1 structure (there are thousands of like that groups):
Group id_7653
{
type register
sub_name 155
1 3123 1 12
2 3124 1 8
3 3125 1 4
4 3126 1 12
5 3127 1 8
6 3128 1 4
.....
}
Group id_8731
{
type register
sub_name 155
1 4331 1 12
2 4332 1 8
3 4333 1 4
4 4334 1 12
5 4335 1 8
6 4336 1 4
.....
}
And here is my $file2 structure (again, there are thousands of defined values)
.....
3123 Spada+1
3124 Spada+2
3125 Spada+3
3126 Spada+4
3127 Spada+5
3128 Spada+6
3129 Spada+7
3130 Spada+8
.....
And here is my Worker script that makes, compares $file1 and $file2.
<?php
//read the first file in as a string
$file1 = file_get_contents("dataparser\names1.txt");
//read the second file in as an array
$file2 = file("dataparser\names2.txt");
//index from file2 that we are going to build
$file2Index = array();
foreach($file2 as $line){
//split the line
$line = explode("\t", $line, 2);
//validate the line, should be only 2 values after explode and first should be a number
if(count($line) == 2 && is_numeric($line[0])){
//add to index
$file2Index[$line[0]] = $line[1];
}
}
//now get all the values from file1 that we want (second column)
preg_match_all('/^\s*\d+\s*(\d+)\s*\d+\s*\d+\s*$/m', $file1, $matches);
$file1Values = array_unique($matches[1]);
//loop over the matches from column 2
foreach($file1Values as $value){
//check if the key doesn't exist
if(!isset($file2Index[$value])){
//echo error message
echo "Value {$value} does not exist in file2<br>";
}
}
?>
What makes that script:
Compares $file1 and $file2 and shows me which values are not defined in $file2
So far, everything works okay.
I want to extend that my script a little bit, so I want to replace that {$value} with my $file2 structure.
This time, I don't want to check that value, I want replace it directly from $file1 value. (Spada etc...)
Which paths I should follow...? Can I get some examples please...

Related

How Do I Implement Incomplete Answer to Old Question

This comment looks like it would work if the author included the value for $numbers. They say it is some type of array, but don't provide enough information to replicate it. I picture some hard coded array ranging from 0 to 9, but I can't help think that such an array would miss numbers greater than 9. What does the numbers array in this example look like?
$text = "1 out of 23";
if(preg_match_all('/\d+/', $text, $numbers))
$lastnum = end($numbers[0]);
I would just post a comment asking whoever wrote that to paste the value for $numbers, but it says I need reputation points to do that.
See How do I grab last number in a string in PHP?
To answer your initial question print_r() can be used to output all contents of an array. e.g. print_r($numbers)
https://3v4l.org/2jA1b
To explain the code:
\d is a single number
+ is a quantifier meaning one or more of the previous character or group
so this would find all numbers in a string. The $numbers[0] would be all numbers, 1 per index, and the end() pulls to the last number/index. Each index would be a number, the 0 is all matches, each indice at the root level is a capture group.
This code wouldn't work as intended for decimals or comma delimited integers. In those cases the numbers would be split up at the delimiter. 1.0 would become 1 and 0 (2 different numbers).
You could rewrite this as:
$text = "1 out of 23";
if(preg_match('/.*\K\D\d+/', $text, $numbers))
echo $numbers[0];
so the end function is not needed. This pulls everything until the last number then forgets everything before the last number.
What you are trying to do is likely easier using preg_split instead of preg_match_all. We can split the input text by the matched regex (digits) and then rebuild the string while incrementing the numbers as we go.
<?php
function incrementNumbers($text) {
// NOTES:
// parenthesis are important in the regex in order to return the captured values
// the -? will capture negative numbers too if necessary
// PREG_SPLIT_DELIM_CAPTURE allows the captured values to be returned too
$split = preg_split('/(-?\d+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$return = '';
foreach($split as $i => $s) {
// because we didn't use PREG_SPLIT_NO_EMPTY, $split[0] will either be an empty string if
// $text began with a number, or the text before the first number. Either way, $split alternates
// between non-number [0], number [1], non-number [2], number [3], etc which is why we can detect
// even or odd indexes to determine if this is a number that needs to be incremented or not
if ($i % 2 === 0) {
$return .= $s;
} else {
$return .= (intval($s) + 1);
}
}
return $return;
}
Examples:
echo incrementNumbers("1 out of 23 with 1 and 1 and 24 and 23");
echo incrementNumbers("1 1 2 2 3 3 2 2 1 1");
echo incrementNumbers("0 1 2 3 4 5 6 7");
echo incrementNumbers("-3 -2 -1 0 1 2 3 4 5 6 7");
echo incrementNumbers("there are no numbers in this text");
echo incrementNumbers("does not start 999 with a number 123 nor end 17 with a number");
Outputs:
2 out of 24 with 2 and 2 and 25 and 24
2 2 3 3 4 4 3 3 2 2
1 2 3 4 5 6 7 8
-2 -1 0 1 2 3 4 5 6 7 8
there are no numbers in this text
does not start 1000 with a number 124 nor end 18 with a number
Working example at https://3v4l.org/iKskO

Php problem, trying to change multiple numbers in a file. Str_replace replaces everything till max

I'm trying to make script that increases all grades in textfile by +1. Like 0 -> 1, 1 -> 2 etc. Grade 5 should not be increased at all, as it's best from 0-5.
Problem is that my script gives following output:
New grades:
5
5
5
5
5
5
When it should give:
New grades:
1
5
2
4
3
5
It seems that str_replace() searches for 0, turns it to 1, then finds that 1 again and replaces it with 2.... and in the end all of grades are 5. Is there way to do this only once for each grade? I tried preg_replace(), but it gives error:
PHP Warning: preg_replace(): Delimiter must not be alphanumeric or backslash
Here's my script:
<?php
$file = 'grades.txt';
$file_contents = file_get_contents($file);
$fh = fopen($file, "w");
$file_contents = str_replace(['0','1','2','3','4'],['1','2','3','4','5'],$file_contents);
fwrite($fh, $file_contents);
fclose($fh);
echo "New grades:\n";
echo $file_contents;
?>
Replace it the other way around - from highest to lowest (instead of lowest to highest). This way you will replace 4 by 5, then there are no 4s - next, you replace 3 by 4, and so on - thus there are no overlaps.
$file_contents = "1 2 3 4 5 4 5 2 1";
$result = str_replace(range(4, 0), range(5, 1), $file_contents);
echo $result;
Live demo at https://3v4l.org/hBB3R

using PHP explode() of a unicode string to get the rows in an array

I am trying to read a tab delimited spreadsheet with unicode characters like this:
$content = file_get_contents($filename);
When I print this in the browser are texts are shown correctly. Also there is a header:
header('Content-Type: text/html; charset=utf-8');
Now I want to split the content into rows by using:
$rows= explode("\n",$content);
The content for the unicode characters now is gibberish when I for instance print one row:
echo $rows[1];
My question is: what is causing this behaviour and what can I do to get the correct texts into the $row array? In the end I want to insert the row values into the database, which currently now inserts the gibberish.
help appreciated
Example
A row before the explode() looks like this (note: tabs are not displayed below):
R002 Студия 2В 66 Богдан
дорога Санкт-Петербург 3174 45 Андрей Смирнов маркетинг 234-56790 653-23685 dummy#dummy.com 34354547
After the explode a row looks like:
R002 ! B C 4 8 O 2 66 > 3 4 0 = 4 > # > 3 0 ! 0 = : B -¬ 5 B 5
# 1 C # 3 3174 45 = 4 # 5 9 ! < 8 # = > 2 < 0 # : 5 B 8 = 3
234-56790 653-23685 dummy#dummy.com 34354547 59
Edit: Also substring not working
I noted also another strange behavious. When I do
echo mb_substr($content,0,50,'utf-8');
the output is only 25 characters, but characters are displayed correctly
R002 Студия 2В 66 Богдан
However when I change the offset form 0 to for instance 5 it's a mess again.
echo mb_substr($content,5,50,'utf-8');
the output is
02 ! B C 4 8 O 2 66 > 3 4 0 = 4 >
not sure what's going on here ... Can it be because the file contains a utf-8 bom ("\xEF\xBB\xBF")?
I found the solution, which had to to with it's encoding. It was exported from Excel which offered initial difficulties. Anyways here is my code to resolve the encoding bit:
$data = file_get_contents($filename);
if (strpos($data, "\xef\xbb\xbf") !== FALSE)
{
//do nothing, it's already utf-8
}
elseif(strpos($data, "\xff\xfe") !== FALSE)
{
$data = iconv('UCS-2', 'UTF-8', $data); //LE UTF-16
}
elseif(strpos($data, "\xfe\xff") !== FALSE)
{
$data = iconv('UCS-2', 'UTF-8', $data); //BE UTF-16
}

PHP - Convert a messy string to a useable one

I have a bunch of data from a football team that needs tidying up. Currently, it looks like this (for demonstration purposes, I've only included 3):
1
Team One
9 7 1 1 31 13 18 22
2
Team Two
9 6 2 1 25 21 4 19
3
Team Three
9 4 3 2 26 18 8 14
For clarity, I'll deconstruct the first 3 lines:
1\t\n
Team One\n
9\t7\t1\t1\t31\t13\t18\t22
Notice how there is a tab and then a linebreak after the position of each team. Then, the team name on the next line, with just a linebreak. And then finally, all of the details about that team. Then the next team's stats start.
I need it to be converted to:
1,Team One,9,7,1,1,31,13,18,22
2,Team Two,9,6,2,1,25,21,4,19
3,Team Three,9,4,3,2,26,18,8,14
Each line starts with the team's position, then team name, then each stat -- all separated by commas.
I've attempted doing this with very little luck. I imagine some kind of fancy regex can do the trick, but I wouldn't know how... hopefully someone can help!
You can use
$in = file("log.txt");
$out = fopen("php://output", "w");
foreach(array_chunk($in, 3) as $group) {
$group = array_map("trim", $group);
$group[2] = implode(",", str_getcsv($group[2], "\t"));
fputcsv($out, $group);
}
Output
1,"Team One","9,7,1,1,31,13,18,22"
2,"Team Two","9,6,2,1,25,21,4,19"
3,"Team Three","9,4,3,2,26,18,8,14"
If you want empty enclosure then use
fputcsv($out, $group, ",", " ");
Output
1, Team One , 9,7,1,1,31,13,18,22
2, Team Two , 9,6,2,1,25,21,4,19
3, Team Three , 9,4,3,2,26,18,8,14
<?php
$resultstr = array();
foreach($Teams as $items){
$resultstr[] = $items['Team One'];
}
$items = implode(", ",$resultstr);
echo $items;
?>
something like that. You can edit it with your own data because you did not mention that in your question.

Undesired new lines added to text document when writing to it

I was just trying to do a simple sorting algorithm on a matrix that I read from a matrix.txt file and append the sorted matrix back to the file.
The problem is that undesired new lines are written to the text file. I also tried in parallel to echo the same things I am writing in the text file, but the echo prints everything okay.
// .. reading the file and sorting the matrix ..
// Write the sorted matrix back to the text file
$handle = #fopen("matrix.txt", "a");
if ($handle) {
fwrite($handle, PHP_EOL . PHP_EOL . "Sorted matrix:" . PHP_EOL);
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $m; $j++) {
echo $matrix[$i][$j] . " ";
fwrite($handle, $matrix[$i][$j] . " ");
}
fwrite($handle, PHP_EOL);
echo "<br>";
}
fclose($handle);
}
matrix.txt file contents:
1 2 5 2 5 8 12 323 1 4
8 32 2 1 3 82 2 8 4 2
1 2 5 2 5 8 12 323 1 4
8 32 2 1 3 82 2 8 4 2
In the web browser it echoes the matrix nicely sorted, each row by itself; however, in the text file, the following is appended:
Matrix sorted using selection sort:
1 1 2 2 4
5 5 8 12 323
1 2 2 2
3 4 8 8 32 82
1 1 2 2 4
5 5 8 12 323
1 2 2 2 3 4 8 8 32 82
Any clues what could cause this? Thanks in advance !
The problem isn't in the code you posted; it's in the input matrix you provided. Notice that every extra newline corresponds to the item which used to be at the end of the row, except for the last row. That's because the final newline from each row is being included when you read the line, and explode (which I imagine you're using) doesn't know to remove it. You could simply trim the lines before exploding to fix this, or specifically remove \r and \n characters.

Categories