php regex matching issue - php

I have this kind of output:
1342&-4&-6
And it could be more times or less:
1342&-4 (I need to replace it with: 1342,1344)
1340&-1&-3&-5&-7 (I need to replace it with: 1340,1341,1343,1345,1347)
I've tried to use preg_match but with no success,
Can someone help me with that?
Thanks,

<?php
//so if you had sting input of "1342&-4" you would get 2 stings returned "1342" and "1344"?
//1340&-1&-3&-5&-7 --> 1340 and 1341 and 1343 and 1345 and 1347
//$str="1342&-4";
$str="1340&-1&-3&-5&-7";
$x=explode('&-',$str);
//print_r($x);
foreach ($x as $k=> $v){
if($k==0){
//echo raw
echo $v."<br>";
}else{
//remove last number add new last number
echo substr($x[0], 0, -1).$v."<br>";
}
}
output:
13401341134313451347
i used <br> you can use what ever you need or add to a new variable(array)

$array = explode('&-', $string);
$len = count($array);
for($i=1; $i<$len; $i++)
$array[$i] += $array[0] / 10 * 10;
var_dump(implode(' ', $array));

Related

How can I grab the index of where the longest identical consecutive portion of a string begins

I'd like the code to output index 6 since d is the starting point in terms of the longest identical consecutive portion in the string.
Not sure what I'm doing wrong here but it's currently returning 3 instead. Seems like I'm going in the right direction but something is missing but I can't pinpoint what.
Any feedback is appreciated! :)
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
$ans = array_search($maxLength, $lengths); // returns 3 but need it to return 6
echo $ans;
$lengths = array_map('strlen', $array);
Above line has only lengths of adjacent similar characters. array_search on max of those lengths will only yield the index where the maximum length is stored. It is totally unrelated with getting the index 6 of your string. If you still wish to get it, you will have to array_sum till that index to get the start index in the actual string.
Snippet:
<?php
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
array_splice($lengths,array_search($maxLength, $lengths));
$ans = array_sum($lengths);
echo $ans;
Online Demo
Alternate Solution:
I would write a simple for loop that uses 2 pointers to keep track of start index of similar characters and record the frequency and start index whenever it is greater than max frequency.
Snippet:
<?php
$str = "abbcccddddcccbba";
$len = strlen($str);
$maxF = 1;
$maxIdx = $startIdx = 0;
for($i = 1; $i < $len; ++$i){
if($str[ $i ] != $str[ $i - 1] || $i === $len - 1){
if($str[ $i ] === $str[ $i - 1] && $i === $len - 1) $i++;
if($maxF < $i - $startIdx){
$maxF = $i - $startIdx;
$maxIdx = $startIdx;
}
$startIdx = $i;
}
}
echo $maxIdx;
Online Demo

PHP function - Order array

Exsists in PHP a function that change the order every time it loops?
I used: array_unshift() but it doesn't do the right job
Example:
1234 (row 1)
4123 (row 2)
3412 (row 3)
2341 (row 4)
Use array_pop to pop and get the element off the end of array, and array_unshift to prepend it to the beginning of the array, then repeat the process for $input iterations.
$input = 5;
$digits = range(1, $input);
for ($i=0; $i<$input; $i++) {
echo implode('', $digits), "\n";
array_unshift($digits, array_pop($digits));
}
Demo.
I am not sure if i have understood you correct but you can try the following:
$data = str_split('12345');
$n = 4;
for($i = 0; $i < $n; $i++) {
echo implode('', $data).'<br />'; //This is for demonstrating purposes
array_unshift($data, array_pop($data));
}
Result:
12345
51234
45123
34512

PHP: sum parts of a string without explode()

I have some strings in this format 15-37;10-38;5-39;, 5-XXS;45-XS;.
Before the - is the quantity, after the - is the size. ; indicates the start of a new pair.
Without having to explode() the string two times, is there a way I can add all the quantities ?
For example, the total quantities for 15-37;10-38;5-39; will be 30.
Thank you.
try with preg_match()
$str ='15-37;10-38;5-39;';
preg_match_all('/(?P<digit>\d+)-/', $str, $matches);
or
preg_match_all('/(\d+)-/', $str, $matches);
echo array_sum($matches[0]); //30
I figured out the following code:
$helper = "15-37;10-38;5-39;";
$sum=0;
for($i=0; $i<$helper.length; $i++){
if($helper[$i]=="-"){
while($helper[$i]!=";")
$i++;
}
else
{
if($helper[$i]!=";"){
$aux="";
while($helper[$i]!="-" && $helper[$i]!=";"){
$aux = $aux.$helper[$i];
//echo $helper[$i]." ";
$k++;
$i++;
}
$i--;
echo (int)$aux."<br>";
$sum = $sum + intval($aux);
}
}
}
echo $sum;
You can test it here: http://writecodeonline.com/php/
The last outputed number is the sum.
Hope it helps!

issue in printing dimension of numbers php

I am just a beginner in PHP. I am trying to write program to print numbers like following.
1 1
12 21
123 321
1234 4321
1234554321
I have written the following code.
<?php
$n=5;
for($i=1; $i<=$n; $i++)
{
echo "<br />";
for($j=1; $j<=$i; $j++)
{
echo $j;
}
}
?>
The result displays the following.
1
12
123
1234
12345
I could not reverse it like
1
21
321
4321
54321
How can I do this?
The simplest, hard coded version:
<?php
$text = "1 1
12 21
123 321
1234 4321
1234554321";
echo $text;
?>
Edit
A more generic solution:
<?php
$n = 5;
$seq1 = '';
$seq2 = '';
$format1 = sprintf("%%-%su", $n); //right justified with spaces
$format2 = sprintf("%%%su", $n); //left justified with spaces
for($i=1; $i<=$n;$i++){
$seq1 .= $i;
$seq2 = strrev($seq1);
echo sprintf("$format1$format2\n", $seq1, $seq2);
};
?>
Okay. What you wrote is pretty good. There need to be several changes in order to do what you wanted though. The first problem is that you are rendering it to HTML - and HTML does not render spaces (which we'll need). Two solutions: you use for space, and make sure you use a proportional font, or you wrap everything into a <pre> tag to achieve pretty much the same thing. So, echo "<pre>"; at the start, echo "</pre>"; at the end.
Next - don't have the inner loop go to $i. Let it go to 5 every time, and print a number if $j <= $i, and a space otherwise.
Then, right next to this loop, do another one, but in reverse (starting with 5 and ending with 1), but doing the very same thing.
Viola is a musical instrument.
Here is my solution to your problem.
It isn't the best solution because it doesn't take into account that you could be using numbers higher than 9, in which case it will push the numbers out of line with each other.
But the point is that it is still the start of a solution that you could work on if needed.
You can use an array to store the numbers you want to print.
Because the numbers are in an array it means we can just use a foreach loop to make sure all of the numbers get printed.
You can use PHP's str_repeat() function to figure out how many spaces you need to put in between each string of numbers.
The below solution will only work if you use an array with the default number indicies as opposed to an associative array.
This is because it uses the $key variable in part of the calculation for the str_repeat() function.
If you would rather not use the $key variable then you should be able to figure out how to change that.
When it come to reversing the numbers they have already been stored in a string so you can just use PHP's strrev() function to take care of that and store them in another variable.
Finally you just have to print a line to the document with a line break at the end.
Note that the str_repeat() function is repeating the HTML entity.
This is because the browser will just compress normal white space down to 1 character.
Also note that I have included a style block to change the font to monospace.
This is to ensure that the numbers all line up with each other.
<style>
html, body {
font: 1em monospace;
}
</style>
<?php
$numbers = array(1, 2, 3, 4, 5);
$numbers_length = count($numbers);
$print_numbers = '';
$print_numbers_rev = '';
foreach($numbers as $key => $value) {
$spaces = str_repeat(' ', ($numbers_length - ($key + 1)) * 2);
$print_numbers .= $value;
$print_numbers_rev = strrev($print_numbers);
echo $print_numbers . $spaces . $print_numbers_rev . '<br />';
}
Edit:
Solution without array:
<style>
html, body {
font: 1em monospace;
}
</style>
<?php
$numbers = 9;
$numbers_length = $numbers + 1;
$print_numbers = '';
$print_numbers_rev = '';
for($i = 0; $i <= $numbers; ++$i) {
$spaces = str_repeat(' ', ($numbers_length - ($i + 1)) * 2);
$print_numbers .= $i;
$print_numbers_rev = strrev($print_numbers);
echo $print_numbers . $spaces . $print_numbers_rev . '<br />';
}
$n = 5;
for ($i = 1; $i <= $n; $i++) {
$counter .= $i;
$spaces = str_repeat(" ", ($n-$i)*2);
echo $counter . $spaces . strrev($counter) . "<br/>";
}
<div style="position:relative;width:100px;height:auto;text-align:right;float:left;">
<?php
$n=5;
for($i=1; $i<=$n; $i++)
{
echo "<br />";
for($j=1; $j<=$i; $j++)
{
echo $j;
}
}
?>
</div>

number increment with customized style

I've tried to do a number(decimal) increment which looks like 001 002 003...123,124 in a loop and couldn't find a simple solution.What I've thought now is to check out whether the number is long enough ,if not prefix it some "0".But it seems not good.Any better ideas?
Thanks.
$x = 6
$y = sprintf("%03d",$x);
http://php.net/manual/en/function.sprintf.php
for($i=1;$i<1000;$i++){
$number = sprintf("%03d",$i);
echo "$number <br />";
}
Two options come immediately to mind. First, try str_pad(). It does exactly what you seem to describe.
Second, you could use sprintf() as another has suggested.
If you are not sure how long the various numbers will turn out to be (e.g., they are determined dynamically and no way of knowing what they will be until afterwards), you can use the following code:
<?php
$numbers = array();
for ($i = 0; $i < 2000; $i++)
{
$numbers[] = $i;
}
array_walk($numbers, function(&$item, $key, $len) { $item = sprintf('%0'.$len.'d', $item); }, strlen(max($numbers)));
print_r($numbers);
?>

Categories