Replace all in a string except of two indexes - php

I have an input like this:
$input="12050301000000000000";
I am trying to use preg_replace to change every thing in my input to 0 except of two chars referenced by their indexes.
For example I want to replace everything except of the first and the second characters to 0.
I tried this:
$input="02050301000000000000";
$index1=0;
$index2=1;
$output= preg_replace('/(?!^'.$index1.')/', '0', $input);

function replace($string, $replace) {
$args = func_get_args();
$string = array_shift($args);
$replace = array_shift($args);
$len = strlen($string);
$i = 0;
$result = '';
while($i < $len) {
$result .= !in_array($i, $args) ? $replace : $string[$i];
$i++;
}
return $result;
}
The function accept an arbitrary number of indexes (int) after $string and $replace
$input="12050301000000000000";
echo $input;
echo '<br>';
echo replace($input, 'a', 1, 3, 5, 7);

it is work for me
$input="02050301000000000000";
$index1=0;
$output = preg_replace("/[^".$index1."+?!^]/", '0', $input );
Thank you..

Suppose you want to replace 1 and 3 indexed values 2 and 5:
$string = '02050301000000000000';
$patterns = array();
$patterns[1] = '/2/';
$patterns[3] = '/5/';
$replacements = array();
$replacements[1] = '0';
$replacements[3] = '0';
$output = preg_replace($patterns, $replacements, $string);
var_dump($output);
Output:
2 and 5 are replaced with 0.
string(20) "00000301000000000000"
For more details have a look on using indexed array in preg_replace:
http://php.net/manual/en/function.preg-replace.php

Related

How to use array to make a string replace function without using the str_replace function?

For example
$string = "Hello world.";
"lo" will get replaced with "aa" and "ld" will get replaced with "bb".
Output will be
$string = "Helaa worbb";
This should work -
$string = "Hello world.";
// pairs to replace
$replace_pairs = array("lo" => 'aa', 'ld' => 'bb');
// loop through pairs
foreach($replace_pairs as $replace => $new)
{
// if present
if(strpos($string, $replace)) {
// explode the string with the key to replace and implode with new key
$string = implode($new, explode($replace, $string));
}
}
echo $string;
Demo
This is what I came up, you can optimize this code.
// assuming only 2 characters find and replace
$string = "Hello world.";
$aa = str_split($string); //converts string into array
$rp1 = 'aa'; //replace string 1
$rp2 = 'bb'; //replace string 2
$f1 = 'lo'; //find string 1
$f2 = 'ld'; // find string 2
function replaceChar($k1, $k2, $findStr, $replaceStr, $arr){
$str = $arr[$k1].$arr[$k2];
if($str == $findStr){
$ra = str_split($replaceStr);
$arr[$k1] = $ra[0];
$arr[$k2] = $ra[1];
}
return $arr;
}
for($i=0; $i < count($aa)-1; $i++){
$k1 = $i;
$k2 = $i+1;
$aa = replaceChar($k1, $k2, $f1, $rp1, $aa); //for replace first match string
$aa = replaceChar($k1, $k2, $f2, $rp2, $aa); // for replace second match string
}
echo implode('', $aa);
Demo

Separate alphabets and numbers from a string

$str = 'ABC300';
How I can get values like
$alphabets = "ABC";
$numbers = 333;
I have a idea , first remove numbers from the string and save in a variable. then remove alphabets from the $str variable and save. try the code
$str = 'ABC300';
$alf= trim(str_replace(range(0,9),'',$str));//removes number from the string
$number = preg_replace('/[A-Za-z]+/', '', $str);// removes alphabets from the string
echo $alf,$number;// your expected output
Try something like this (it's not that fast)...
$string = "ABCDE3883475";
$numbers = "";
$alphabets = "";
$strlen = strlen($string);
for($i = 0; $i <= $strlen; $i++) {
$char = substr($string, $i, 1);
if(is_numeric($char)) {
$numbers .= $char;
} else {
$alphabets .= $char;
}
}
Then all numbers should be in $numbers and all alphabetical characters should be in $alphabets ;)
https://3v4l.org/Xh4FR
A way to do that is to find all digits and use the array to replace original string with the digits inside.
For example
function extractDigits($string){
preg_match_all('/([\d]+)/', $string, $match);
return $match[0];
}
$str = 'abcd1234ab12';
$digitsArray = extractDigits($str);
$allAlphas = str_replace($digitsArray,'',$str);
$allDigits = '';
foreach($digitsArray as $digit){
$allDigits .= $digit;
}

Find all letters not used in a string

I want to be able to do something likes this:
$str="abc";
echo findNot($str); //will echo "defghijklomnopqrstuvwxyz"
$str2="happy birthday";
echo findNot($str2); //will echo "cfgjklmnoqsuvwxz"
Basically, it would find all letters not represented in the string and return them in an array or string.
I could do this easily with a foreach and arrays of characters, but I was wondering if anyone had a more elegant solution.
Here's what I came up with.
function findNot($str){
return array_diff(range('a','z'), array_unique(str_split(strtolower($str))));
}
How about this
$str="abc";
var_dump(findNot($str));
function findNot($string)
{
$letters = range('a', 'z');
$presents = array_map(function($i) { return chr($i); }, array_keys(array_filter(count_chars($string))));
return array_diff($letters, $presents);
}
PS: implode the result if you need a string of chars, not array
PPS: not sure if it is a "more elegant" solution :-)
PPPS: another solution I could think of is
$str="abc";
var_dump(findNot($str));
function findNot($string)
{
$letters = range('a', 'z');
$presents = str_split(count_chars($string, 4));
return array_intersect($letters, $presents);
}
You could do something like this:
$text = 'abcdefghijklmnop';
$search = array('a','b','c');
$result = str_replace($search, '', $text);
Zerk's solution is nice. I came up with this similar example, not as elegant.
<?php
$alphabet = 'abcdefghijklmnopqrstuvwxyz';
$alphabet = preg_split('//', $alphabet, -1, PREG_SPLIT_NO_EMPTY);
$str="abc";
var_dump( findNot($str) ); //will echo "defghijklomnopqrstuvwxyz"
$str2="happy birthday";
var_dump( findNot($str2) ); //will echo "cfgjklmnoqsuvwxz"
function findNot($str)
{
global $alphabet;
$str = str_replace(' ', '', $str);
$chars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
$chars = array_unique($chars);
sort($chars);
$diff = array_diff($alphabet, $chars);
return $diff;
}

PHP - Most efficient way to extract substrings based on given delimiter?

I have a string that contains some values I need to extract. Each of these values is surrounded by a common character.
What is the most efficient way to extract all of these values into an array?
For example, given the following string:
stackoverflowis%value1%butyouarevery%value2%
I would like to get an array containing value1 and value2
$s = "stackoverflowis%value1%butyouarevery%value2%";
preg_match_all('~%(.+?)%~', $s, $m);
$values = $m[1];
preg_match_all
$string = 'stackoverflowis%value1%butyouarevery%value2%';
$string = trim( $string, '%' );
$array = explode( '%' , $string );
$str = "stackoverflowis%value1%butyouarevery%value2%";
preg_match_all('/%([a-z0-9]+)%/',$str,$m);
var_dump($m[1]);
array(2) { [0]=> string(6) "value1" [1]=> string(6) "value2" }
Give a try to explode. Like $array = explode('%', $string);
LE:
<?php
$s = 'stackoverflowis%value1%butyouarevery%value2%';
$a = explode('%', $s);
$a = array_filter($a, 'strlen'); // removing NULL values
$last = ''; // last value inserted;
for($i=0;$i<=count($a);$i++)
if (isset($a[$i+1]) && $a[$i] <> $last)
$t[] = $last = $a[$i+1];
echo '<pre>'; print_r($t); echo '</pre>';
Use explode and take the odd-indexed values from the resulting array. You indicated you wanted the most efficient method, and this will be faster than a regex solution.
$str = 'stackoverflowis%value1%butyouarevery%value2%';
$arr = explode('%', $str);
$ct = count($arr);
for ($i = 1; $i < $ct; $i += 2) {
echo $arr[$i] . '<br />';
}
preg_match_all('/%([^%]+)%/', $s, $match);
var_dump($match[1]);

Modify numbers inside a string PHP

I have a string like this:
$string = "1,4|2,64|3,0|4,18|";
Which is the easiest way to access a number after a comma?
For example, if I have:
$whichOne = 2;
If whichOne is equal to 2, then I want to put 64 in a string, and add a number to it, and then put it back again where it belongs (next to 2,)
Hope you understand!
genesis'es answer with modification
$search_for = 2;
$pairs = explode("|", $string);
foreach ($pairs as $index=>$pair)
{
$numbers = explode(',',$pair);
if ($numbers[0] == $search_for){
//do whatever you want here
//for example:
$numbers[1] += 100; // 100 + 64 = 164
$pairs[index] = implode(',',$numbers); //push them back
break;
}
}
$new_string = implode('|',$pairs);
$numbers = explode("|", $string);
foreach ($numbers as $number)
{
$int[] = intval($number);
}
print_r($int);
$string = "1,4|2,64|3,0|4,18|";
$coordinates = explode('|', $string);
foreach ($coordinates as $v) {
if ($v) {
$ex = explode(',', $v);
$values[$ex[0]] = $ex[1];
}
}
To find the value of say, 2, you can use $whichOne = $values[2];, which is 64
I think it is much better to use the foreach like everyone else has suggested, but you could do it like the below:
$string = "1,4|2,64|3,0|4,18|";
$whichOne = "2";
echo "Starting String: $string <br>";
$pos = strpos($string, $whichOne);
//Accomodates for the number 2 and the comma
$valuepos = substr($string, $pos + 2);
$tempstring = explode("|", $valuepos);
$value = $tempstring[0]; //This will ow be 64
$newValue = $value + 18;
//Ensures you only replace the index of 2, not any other values of 64
$replaceValue = "|".$whichOne.",".$value;
$newValue = "|".$whichOne.",".$newValue;
$string = str_replace($replaceValue, $newValue, $string);
echo "Ending String: $string";
This results in:
Starting String: 1,4|2,64|3,0|4,18|
Ending String: 1,4|2,82|3,0|4,18|
You could run into issues if there is more than one index of 2... this will only work with the first instance of 2.
Hope this helps!
I know this question is already answered, but I did one-line solution (and maybe it's faster, too):
$string = "1,4|2,64|3,0|4,18|";
$whichOne = 2;
$increment = 100;
echo preg_replace("/({$whichOne},)(\d+)/e", "'\\1'.(\\2+$increment)", $string);
Example run in a console:
noice-macbook:~/temp% php 6642400.php
1,4|2,164|3,0|4,18|
See http://us.php.net/manual/en/function.preg-replace.php

Categories