How to add number from string - php

I want to add number from my string. this is my string
$formula = 'IF(B15="","",IF(ISNUMBER(A14),A14+1,IF(ISNUMBER(B3),B3+1,1)))';
i want add number if before the number is alphabet. for example i want to make B15 to B16 ini my string.. this my loop
$jum = strlen($formula);
for($i = 0; $i < $jum; $i++){
if(ctype_alpha($formula[$i]) && ctype_alnum($formula[$i+1])){
$temp_formula[$i+1] += 1;
}
}

You can do this with preg_replace_callback. Use this regex, which looks for a symbol of the form <letter><digits> between word boundaries:
\b([A-Z])(\d+)\b
and then in the callback the second group's value can be incremented:
$formula = 'IF(B15="","",IF(ISNUMBER(A14),A14+1,IF(ISNUMBER(B3),B3+1,1)))';
echo preg_replace_callback('/\b([A-Z])(\d+)\b/', function ($m) {
return $m[1] . (1 + $m[2]);
}, $formula);
Output:
IF(B16="","",IF(ISNUMBER(A15),A15+1,IF(ISNUMBER(B4),B4+1,1)))
Demo on 3v4l.org
Update
To use an external variable in the callback (as described in the comments), edit the code like this:
$formula = 'IF(B15="","",IF(ISNUMBER(A14),A14+1,IF(ISNUMBER(B3),B3+1,1)))';
$tambah = $adding + ($rekord*$highest);
echo preg_replace_callback('/\b([A-Z])(\d+)\b/', function ($m) use ($tambah) {
return $m[1] . ($tambah + $m[2]);
}, $formula);

Related

String between string with array in PHP, array order ISSUE

I'm facing an issue with a function that gets a string between two other strings.
function string_between($str, $starting_word, $ending_word) {
$subtring_start = strpos($str, $starting_word);
$subtring_start += strlen($starting_word);
foreach ($ending_word as $a){
$size = strpos($str, $a, $subtring_start) - $subtring_start;
}
return substr($str, $subtring_start, $size);
}
The issue is that the function searches for the first ending_word in the array.
An example will be easier to understand:
$array_a = ['the', 'amen']; // Starting strings
$array_b = [',', '.']; // Ending strings
$str = "Hello, the world. Then, it is over.";
Expected result:
"the world."
Current result:
"the world. Then,"
The function will think that the ending_word is "," because it is the first element met in the array_b. However, the text encounters first the '.' after the "the" starting word.
How can I make sure the function goes through the text and stops at the first element in the $str present in the array_b, whatever the position in the array?
Any idea?
Basically, you need to break outside of your foreach loop when $size > 0
That way it stops looping through your array when it finds the 1st occurrence. Here is the more complete code with other fixes:
function stringBetween($string, $startingWords, $endingWords) {
foreach ($startingWords as $startingWord) {
$subtringStart = strpos($string, $startingWord);
if ($subtringStart > 0) {
foreach ($endingWords as $endingWord){
$size = strpos($string, $endingWord, $subtringStart) - $subtringStart + strlen($endingWord);
if ($size > 0) {
break;
}
}
if ($size > 0) {
return substr($string, $subtringStart, $size);
}
}
}
return null;
}
$startArr = array('the', 'amen'); // Starting strings
$endArr = array('.', ','); // Ending strings
$str = "Hello, the world. Then, it is over.";
echo stringBetween($str, $startArr, $endArr); // the world.
This type of problems are best solved by PCRE regexes, only couple of lines needed in function :
function string_between($str, $starts, $ends) {
preg_match("/(?:{$starts}).*?(?:{$ends})/mi", $str, $m);
return $m[0];
}
Then calling like this :
echo string_between("Hello, the world. Then, it is over.", 'the|amen', ',|\.');
Produces : the world.
The trick,- search to the nearest matching ending symbol is done with regex non-greedy seach, indicated by question symbol in pattern .*?. You can even extend this function to accept arrays as starting/ending symbols, just that case modify function (possibly with implode('|',$arr)) for concatenating symbols into regex grouping formula.
Edited version
This works now. Iterate over your teststrings from first array looking for position of occurance from teststring. If found one then search for the second teststring at startposition from end of first string.
To get the shortest hit I store the position from the second and take the minimum.
You can try it at http://sandbox.onlinephpfunctions.com/code/0f1e5c97da62b4daaf0e49f52271fe288d1cacbb
$array_a =array('the','amen');
$array_b =array(',','.', '#');
$str = "Hello, the world. Then, it is over.";
function earchString($str, $array_a, $array_b) {
forEach($array_a as $test) {
$pos = strpos($str, $test);
if ($pos===false) continue;
$found = [];
forEach($array_b as $test2) {
$posStart = $pos+strlen($test);
$pos2 = strpos($str, $test2, $posStart);
$found[] = ($pos2!==false) ? $pos2 : INF;
}
$min = min($found);
if ($min !== INF)
return substr($str,$pos,$min-$pos) .$str[$min];
}
return '';
}
echo earchString($str, $array_a, $array_b);

PHP string challenge

I have an string such as
$string = "This is my test string {ABC}. This is test {XYZ}. I am new for PHP {PHP}".
Now I need to replace occurrence of string within {}, in such a way that output will be:
This is my test string {ABC 1}. This is test {XYZ 2}. I am new for PHP {PHP 3}".
I am looking to resolve this with recursive function but not getting expected result.
$i = 1;
echo preg_replace_callback('/\{(.+?)\}/', function (array $match) use (&$i) {
return sprintf('{%s %d}', $match[1], $i++);
}, $string);
The "trick" is to simply keep an external counter running, here $i, which is used in the anonymous callback via use (&$i).
There is no recursion here. Simply counting.
$result = preg_replace_callback("/\{([^}]*+)\}/",function($m) {
static $count = 0;
$count++;
return "{".$m[1]." ".$count."}";
},$string);
If you really need recursive :^ )
$string = "This is my test string {ABC}. This is test {XYZ}. I am new for PHP {PHP}";
function my_replace($string, $count = 1)
{
if ($string)
{
return preg_replace_callback('/\{(.+?)\}(.*)$/', function (array $match) use ($count)
{
return sprintf('{%s %d} %s', $match[1], $count, my_replace($match[2], $count + 1));
}, $string, 1);
}
}
echo my_replace($string);

Find the position of the first occurrence of any number in string

Can someone help me with algorithm for finding the position of the first occurrence of any number in a string?
The code I found on the web does not work:
function my_offset($text){
preg_match('/^[^\-]*-\D*/', $text, $m);
return strlen($m[0]);
}
echo my_offset('[HorribleSubs] Bleach - 311 [720p].mkv');
The built-in PHP function strcspn() will do the same as the function in Stanislav Shabalin's answer when used like so:
strcspn( $str , '0123456789' )
Examples:
echo strcspn( 'That will be $2.95 with a coupon.' , '0123456789' ); // 14
echo strcspn( '12 people said yes' , '0123456789' ); // 0
echo strcspn( 'You are number one!' , '0123456789' ); // 19
HTH
function my_offset($text) {
preg_match('/\d/', $text, $m, PREG_OFFSET_CAPTURE);
if (sizeof($m))
return $m[0][1]; // 24 in your example
// return anything you need for the case when there's no numbers in the string
return strlen($text);
}
function my_ofset($text){
preg_match('/^\D*(?=\d)/', $text, $m);
return isset($m[0]) ? strlen($m[0]) : false;
}
should work for this. The original code required a - to come before the first number, perhaps that was the problem?
I can do regular expressions but I have to go into an altered state to
remember what it does after I've coded it.
Here is a simple PHP function you can use...
function findFirstNum($myString) {
$slength = strlen($myString);
for ($index = 0; $index < $slength; $index++)
{
$char = substr($myString, $index, 1);
if (is_numeric($char))
{
return $index;
}
}
return 0; //no numbers found
}
Problem
Find the first occurring number in a string
Solution
Here is a non regex solution in javascript
var findFirstNum = function(str) {
let i = 0;
let result = "";
let value;
while (i<str.length) {
if(!isNaN(parseInt(str[i]))) {
if (str[i-1] === "-") {
result = "-";
}
while (!isNaN(parseInt(str[i])) && i<str.length) {
result = result + str[i];
i++;
}
break;
}
i++;
}
return parseInt(result);
};
Example Input
findFirstNum("words and -987 555");
Output
-987

php: dynamic preg_replace

The code below is not a functioning method it's just written to help you understand what I'm trying to do.
// $i = occurrence to replace
// $r = content to replace
private function inject($i, $r) {
// regex matches anything in the format {value|:value}
$output = preg_replace('/\{(.*?)\|\:(.*?)\}/', '$r', $this->source);
$output[$i]
}
How do I find the $i occurrence in $output; and replace it with $r;?
Note: All I want to do is use $i (which is a number) to find the occurrence of that nmber in a preg_replace; For exmaple: I might want to replace the second occurrence of the preg_replace pattern with the variable $r
I think you can only accomplish such an occurence counting with a callback:
private function inject($i, $r) {
$this->i = $i;
$this->r = $r;
// regex matches anything in the format {value|:value}
$output = preg_replace_callback('/\{(.*?)\|\:(.*?)\}/',
array($this, "inject_cb"), $this->source);
}
function inject_cb($match) {
if ($this->i --) {
return $match[0];
}
else {
return $this->r;
}
}
It leaves the first $i matches as is, and uses the tempoary $this->r once when the countdown is matched. Could be done with a closure to avoid ->$i and ->$r however.

built in function to combine overlapping string sequences in php?

Is there a built in function in PHP that would combine 2 strings into 1?
Example:
$string1 = 'abcde';
$string2 = 'cdefg';
Combine to get: abcdefg.
If the exact overlapping sequence and the position are known, then it is possible to write a code to merge them.
TIA
I found the substr_replace method to return funny results.
Especially when working with url strings. I just wrote this function.
It seems to be working perfectly for my needs.
The function will return the longest possible match by default.
function findOverlap($str1, $str2){
$return = array();
$sl1 = strlen($str1);
$sl2 = strlen($str2);
$max = $sl1>$sl2?$sl2:$sl1;
$i=1;
while($i<=$max){
$s1 = substr($str1, -$i);
$s2 = substr($str2, 0, $i);
if($s1 == $s2){
$return[] = $s1;
}
$i++;
}
if(!empty($return)){
return $return;
}
return false;
}
function replaceOverlap($str1, $str2, $length = "long"){
if($overlap = findOverlap($str1, $str2)){
switch($length){
case "short":
$overlap = $overlap[0];
break;
case "long":
default:
$overlap = $overlap[count($overlap)-1];
break;
}
$str1 = substr($str1, 0, -strlen($overlap));
$str2 = substr($str2, strlen($overlap));
return $str1.$overlap.$str2;
}
return false;
}
Usage to get the maximum length match:
echo replaceOverlap("abxcdex", "xcdexfg"); //Result: abxcdexfg
To get the first match instead of the last match call the function like this:
echo replaceOverlap("abxcdex", "xcdexfg", “short”); //Result: abxcdexcdexfg
To get the overlapping string just call:
echo findOverlap("abxcdex", "xcdexfg"); //Result: array( 0 => "x", 1 => "xcdex" )
It's possible using substr_replace() and strcspn():
$string1 = 'abcde';
$string2 = 'cdefgh';
echo substr_replace($string1, $string2, strcspn($string1, $string2)); // abcdefgh
No, there is no builtin function, but you can easily write one yourself by using substr and a loop to see how much of the strings that overlap.

Categories