More complicated range generation - php

Producing a range with PHP is easy when the range is something like 1 to 100 or A to Z. But I need to be able to produce ranges like 101A to 101Z or A1 to A100.
I thought that maybe PHP has a function to compare two strings, strip what's common between them and return the rest to form the range boundaries. However I can not find such a function. How would I achieve this?
EDIT: I don't have control over the format, I can only set the guidelines. The end user determines the pattern by entering something like A1-A100 into an input field.

101A to 101Z is like "101" + range("A", "Z")
and
A1 to A100 is like "A" + range(1, 100)
If you're looking for A1 to Z100 that's when things get a bit more complicated.
You can look at the way functions like base converters work, like dechex and base64_encode
If you're converting from the decimal system to your own notation you can do thing kind of conversion.
1 => A1
2 => A2
101 => B1
102 => B2
2601? => Z1
2700? => Z100
This just describes the outline. If you want code you'll have to make your question more clear.
Arbitrary ranges is .. very hard. I don't know of a solution. A1-A100 has a clear solution, but what about A1-100Z, how do you even begin? What about small-large or Boston-New York?

You can try with:
function rangeFix($from, $to, $prefix = null, $suffix = null) {
return array_map(function($item) use ($prefix, $suffix){
return $prefix . $item . $suffix;
}, range($from, $to));
}
rangeFix(0, 10, 'A', 'Z');
Output:
array (size=11)
0 => string 'A0Z' (length=3)
1 => string 'A1Z' (length=3)
2 => string 'A2Z' (length=3)
3 => string 'A3Z' (length=3)
4 => string 'A4Z' (length=3)
5 => string 'A5Z' (length=3)
6 => string 'A6Z' (length=3)
7 => string 'A7Z' (length=3)
8 => string 'A8Z' (length=3)
9 => string 'A9Z' (length=3)
10 => string 'A10Z' (length=4)
or:
rangeFix('A', 'Z', 101);
Output:
array (size=26)
0 => string '101A' (length=4)
1 => string '101B' (length=4)
2 => string '101C' (length=4)
3 => string '101D' (length=4)
4 => string '101E' (length=4)
5 => string '101F' (length=4)
6 => string '101G' (length=4)
7 => string '101H' (length=4)
8 => string '101I' (length=4)
9 => string '101J' (length=4)
10 => string '101K' (length=4)
11 => string '101L' (length=4)
12 => string '101M' (length=4)
13 => string '101N' (length=4)
14 => string '101O' (length=4)
15 => string '101P' (length=4)
16 => string '101Q' (length=4)
17 => string '101R' (length=4)
18 => string '101S' (length=4)
19 => string '101T' (length=4)
20 => string '101U' (length=4)
21 => string '101V' (length=4)
22 => string '101W' (length=4)
23 => string '101X' (length=4)
24 => string '101Y' (length=4)
25 => string '101Z' (length=4)

This is my own, not so elegant solution. It works with the following logic:
Range boundaries have two parts, of which the other is digit and the other non-digit, such as A1 or 1A. One-part string work too, such as A or 1. I did not test with strings such as A1B where there are more than two parts. The script probably fails there.
$s1 = '101A';
$s2 = '101Z';
$s1_d = preg_split('/\d+/', $s1);
$s1_D = preg_split('/\D+/', $s1);
$s2_d = preg_split('/\d+/', $s2);
$s2_D = preg_split('/\D+/', $s2);
if($s1_d[0] == '') $s1_d[0] = $s1_D[0];
else $s1_d[1] = $s1_D[1];
$s1 = $s1_d;
if($s2_d[0] == '') $s2_d[0] = $s2_D[0];
else $s2_d[1] = $s2_D[1];
$s2 = $s2_d;
$prefix = false;
$postfix = false;
if($s1[0] == $s2[1]) die(); // Can't do it.
if($s1[0] == $s2[0]) {
$prefix = $s1[0];
$start = $s1[1];
$end = $s2[1];
}
else {
$postfix = $s1[1];
$start = $s1[0];
$end = $s2[0];
}
$range = range($start, $end);
foreach($range as &$r) {
$r = $prefix . $r . $postfix;
}
var_dump($range);

Related

PHP str_split on string with decoded html_entity

If I run this code:
<?php
$string = 'My string ‘to parse’';
$string_decoded = html_entity_decode($string, ENT_QUOTES, 'utf-8');
$string_array = str_split($string_decoded);
var_dump($string_array);
?>
I get this result:
array (size=28)
0 => string 'M' (length=1)
1 => string 'y' (length=1)
2 => string ' ' (length=1)
3 => string 's' (length=1)
4 => string 't' (length=1)
5 => string 'r' (length=1)
6 => string 'i' (length=1)
7 => string 'n' (length=1)
8 => string 'g' (length=1)
9 => string ' ' (length=1)
10 => string '�' (length=1)
11 => string '�' (length=1)
12 => string '�' (length=1)
13 => string 't' (length=1)
14 => string 'o' (length=1)
15 => string ' ' (length=1)
16 => string 'p' (length=1)
17 => string 'a' (length=1)
18 => string 'r' (length=1)
19 => string 's' (length=1)
20 => string 'e' (length=1)
21 => string '�' (length=1)
22 => string '�' (length=1)
23 => string '�' (length=1)
As you can see, instead of the decoded single quotes (left/right), I'm getting these three characters for each quote...
I noticed that this happens with some entities, but not others. A few that present this issue are ‘ ” $copy;. Some that don't present the same problem are & $gt;.
I tried different charsets but couldn't find one that would work for all.
What am I doing wrong? Is there a way to make it work for all entities? Or at least all the "common" ones?
Thanks.
This should do well:
function mb_str_split($string) {
return preg_split('/(?<!^)(?!$)/u', $string );
}
$string = 'My string ‘to parse’';
$string = utf8_encode($string);
$string_decoded = html_entity_decode($string, ENT_QUOTES, 'utf-8');
$string_array = mb_str_split($string_decoded);
var_dump($string_array);
As mentioned in comments: you need to split the string with mb_split or by regex.
Proof: https://3v4l.org/3FRmG

2 Arrays of data that refill on a loop, how to turn data to insert query

I have 2 Arrays I've read from a text file, one is the Field name the other the field data.
array (size=12) //name $columns
0 => string 'Name' (length=4)
1 => string 'Telephone' (length=9)
2 => string 'Email' (length=5)
3 => string 'selling' (length=7)
4 => string 'buying' (length=6)
5 => string 'textarea' (length=8)
6 => string 'Country' (length=7)
7 => string 'IP' (length=2)
8 => string 'Referer' (length=7)
9 => string 'Server Time' (length=11)
10 => string 'Browser' (length=7)
11 => string 'User Agent' (length=10)
array (size=12) //name $values
0 => string ' john smith' (length=12)
1 => string ' 01234 567 897' (length=14)
2 => string ' test#test.com' (length=32)
3 => string ' Euros and US$' (length=14)
4 => string ' Euros and US$' (length=14)
5 => string ' Notes bur selling $ traveller cheques' (length=38)
6 => string ' UNITED KINGDOM' (length=15)
7 => string ' 11.222.33.44' (length=14)
8 => string ' http//www.anaddress.html' (length=48)
9 => string ' 2011-12-09 07' (length=14)
10 => string ' Firefox' (length=8)
11 => string ' Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv1.9.2.24) Gecko/20111103 Firefox/3.6.24' (length=95)
Now I want to insert these into a table, now problem 1) is construction the mysql query. problem 2) Is i'm sure some of these text files i'm looping through some of the columns will be different, how can i get it to if the column doesn't exist to create it and carry on.
I'm a relative noob, with a little coding background, but this is beating me.
I'm using php 5.4.12 and a local host wamp server.
Please help, so i can learn.
You need to be sure that all the $columns var exists in your table.
If not you can compare them first by using DESCRIBE table and then parsing to check if the column exists or not.
if ( sizeof($columns) != sizeof($values) ) die() ;
$col_table = Array() ;
$sql = ' describe `table` ' ;
$rq = ... ; // Do your request
while ( $d = mysql_fetch_assoc($rq) )
{
$col_table[] = $d['Field'] ;
}
foreach ( $columns as $index => $colname )
{
if ( ! in_array($colname,$col_table) )
{
// There is a problem here... Your colname doesn't exists, you need to skip the entry $index for cols and vals
unset($columns[$index]) ;
unset($values[$index]) ;
}
}
And after that,
if ( sizeof($columns) == sizeof($values) )
{
$sql = ' insert into table (`'.implode('`,`',$columns).'`) values (' ;
$temp = Array() ;
foreach ( $values as $val ) $temp[] = '"'.mysql_escape_string($val).'"' ;
$sql .= implode(', ',$temp) ;
$sql .= ')' ;
}

Preg_replace not working as wanted

Basically i have the following text stored in $text var :
$text = 'An airplane accelerates down a runway at 3.20 m/s2 for 32.8 s until is finally lifts off the ground. Determine the distance traveled before takeoff'.
I have a function that replaces some keywords on the text from an array named $replacements which is (I did a var_dump on it) :
'm' => string 'meter' (length=5)
'meters' => string 'meter' (length=5)
's' => string 'second' (length=6)
'seconds' => string 'second' (length=6)
'n' => string 'newton' (length=6)
'newtons' => string 'newton' (length=6)
'v' => string 'volt' (length=4)
'speed' => string 'velocity' (length=8)
'\/' => string 'per' (length=3)
's2' => string 'secondsquare' (length=12)
The text goes through the following function :
$toreplace = array_keys($replacements);
foreach ($toreplace as $r){
$text = preg_replace("/\b$r\b/u", $replacements[$r], $text);
}
However, there is a difference between what I expect and the output :
Expected Output : an airplane accelerates down runway at 3.20 meterpersecondsquare for 32.8 second until finally lifts off ground determine distance traveled before takeoff
Function Output : an airplane accelerates down runway at 3.20 meterpers2 for 32.8 second until finally lifts off ground determine distance traveled before takeoff
Notice that I expect 'meterpersecondsquare' and I get 'meterpers2' (the 's2' isn't replaced) while the 'm' and '/' were replaced with their values.
I noticed that when I put m/s instead of m/s2 it works fine and gives :
an airplane accelerates down runway at 3.20 meterpersecond for 32.8 second until finally lifts off ground determine distance traveled before takeoff
So the problem is basically it doesn't match that s2. Any thoughts why is it the case?
Move the s2 replacement before the s replacement.
Since you are doing the replacement one at a time, you are destroying the s2 before it gets a chance to replace it.
3.20 m/s2 will be transformed like this
[m] 3.20 meter/s2
[s] 3.20 meter/second2
[/] 3.20 meterpersecond2
Which results in meterpersecond2
Here is the proper order
'm' => string 'meter' (length=5)
'meters' => string 'meter' (length=5)
's2' => string 'secondsquare' (length=12)
's' => string 'second' (length=6)
'seconds' => string 'second' (length=6)
'n' => string 'newton' (length=6)
'newtons' => string 'newton' (length=6)
'v' => string 'volt' (length=4)
'speed' => string 'velocity' (length=8)
'\/' => string 'per' (length=3)

JpGraph : no error but broken picture

I make a graph with JPGraph but I've a little problem.
No error was displayed but the picture is a "broken picture".
Here is my code :
$graph = new Graph(1000,300);
$graph->img->SetMargin(40,30,50,40);
$graph->SetScale("textlin");
$graph->title->Set("Graph");
$graph->ygrid->Show();
$graph->ygrid->SetColor('blue#0.7');
$graph->ygrid->SetLineStyle('dashed');
$graph->xgrid->Show();
$graph->xgrid->SetColor('red#0.7');
$graph->xgrid->SetLineStyle('dashed');
$graph->title->SetFont(FF_ARIAL,FS_BOLD,11);
$bigCourbe = array();
$i = 0;
foreach($bigData as $data)
{
var_dump($data);
$courbe = new LinePlot($data);
$courbe->value->Show();
$courbe->value->SetFont(FF_ARIAL,FS_NORMAL,9);
$courbe->value->SetFormat('%d');
$courbe->mark->SetType(MARK_FILLEDCIRCLE);
$courbe->mark->SetFillColor("green");
$courbe->mark->SetWidth(2);
$courbe->SetWeight(10);
echo $function[$i];
$courbe->SetLegend($function[$i++]);
$bigCourbe[] = $courbe;
}
$graph->xaxis->title->Set("Heures");
$graph->yaxis->title->SetFont(FF_FONT1,FS_BOLD);
$graph->xaxis->title->SetFont(FF_FONT1,FS_BOLD);
foreach ($bigCourbe as $elem) {
$graph->Add($elem);
}
//$graph->Stroke();
So, the result seems good :
array (size=24)
0 => string '0.000' (length=5)
1 => string '0.000' (length=5)
2 => string '0.000' (length=5)
3 => string '0.000' (length=5)
4 => string '0.000' (length=5)
5 => string '0.000' (length=5)
....
Index HC <- it's the $function[$i] var
array (size=24)
0 => string '0.200' (length=5)
1 => string '0.200' (length=5)
2 => string '0.100' (length=5)
3 => string '0.200' (length=5)
4 => string '0.200' (length=5)
5 => string '0.200' (length=5)
....
Index HP
array (size=24)
0 => string '0.000' (length=5)
1 => string '0.000' (length=5)
2 => string '0.000' (length=5)
3 => string '0.000' (length=5)
4 => string '0.000' (length=5)
5 => string '0.000' (length=5)
Index HPTE
array (size=24)
0 => string '0.200' (length=5)
1 => string '0.200' (length=5)
2 => string '0.100' (length=5)
3 => string '0.200' (length=5)
4 => string '0.200' (length=5)
5 => string '0.200' (length=5)
....
Total Heure
I do not see the problem...
If I remove the debug, and uncomment the $graph->Stroke(); line. I have that :
Can you help me ?
Thank you in advance.
in my case (php 7.1.0) it was Deprecated message
just put
ini_set('display_errors', 0);
at the top of your script and try again.
or
comment out $graph->Stroke(); and see what error(or warning) you have
I know this is an old question but I just had the same problem and fixed it by removing everything before the <?php.
THis was suggested in the link below - check 1.b.
Solution Source
How do you display the graph? Do you have an HTML page? Please show the HTML code.
I have a similar problem where I have no error message, but get the broken image icon.
jpGraph can't include PHP file
One thing I would recommend is to add the lines
//save to file
$fileName = "/tmp/imagefile.png";
$graph->img->Stream($fileName);
if the image from the file is correct, then you can rule out the graph generating code.

Get text that is within brackets with single or double quotes

I try to found in my all PHP files the strings inside the i18n functions. Here is an example:
$string = '__("String 2"); __("String 3", __("String 4"));' . "__('String 5'); __('String 6', __('String 7'));";
var_dump(preg_match_all('#__\((\'|")([^\'"]+)(\'|")\)#', $string, $match));
var_dump($match);
I wanna get this result:
array
0 => array
0 => string 'String 2' (length=8)
1 => string 'String 3' (length=8)
2 => string 'String 4' (length=8)
3 => string 'String 5' (length=8)
4 => string 'String 6' (length=8)
4 => string 'String 7' (length=8)
But unfortunately I get this result
array
0 => array
0 => string '__("esto es una prueba")' (length=24)
1 => string '__("esto es una prueba 2")' (length=26)
2 => string '__("prueba 4")' (length=14)
3 => string '__('caca')' (length=10)
4 => string '__('asdsnasdad')' (length=16)
1 => array
0 => string '"' (length=1)
1 => string '"' (length=1)
2 => string '"' (length=1)
3 => string ''' (length=1)
4 => string ''' (length=1)
2 => array
0 => string 'esto es una prueba' (length=18)
1 => string 'esto es una prueba 2' (length=20)
2 => string 'prueba 4' (length=8)
3 => string 'caca' (length=4)
4 => string 'asdsnasdad' (length=10)
3 => array
0 => string '"' (length=1)
1 => string '"' (length=1)
2 => string '"' (length=1)
3 => string ''' (length=1)
4 => string ''' (length=1)
Thanks in advance.
preg_match_all('/(?<=\(["\']).*?(?=[\'"])/', $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
Simple.
Note that I am using ( as an entry point to the match. If you have more exotic input you should provide it.
Don't capture the quotes.
preg_match_all('#__\([\'"]([^\'"]+)[\'"]\)#', $string, $match);
Also take a look at the flags parameter for preg_match_all() for different output formats.

Categories