i have
$str ="GOODDAY"
and i need to replace O with U , but not change ALL O characters.
For example
$str1 ="GUODDAY" ;
$str2 ="GOUDDAY" ;
$str3 ="GUUDDAY" ;
i used str_replace but only get $str3 , any idea?
It looks like you want to print the string as many times as the occurrences of O, and replace O once each time, according to the iteration number, and finally print the string with all O replaced. This will do it:
$str = "GOODDAY";
$find = "O";
$replaceWith = "U";
$lastPos = 0;
while (($lastPos = strpos($str, $find, $lastPos)) !== false) {
echo substr_replace($str, $replaceWith, $lastPos, 1) . "\n";
$lastPos = $lastPos + strlen($find);
}
echo str_replace($find, $replaceWith, $str);
https://3v4l.org/ddg73
Maybe something like this :
$str ="GOODDAY";
for ($i = 0; $i < strlen($str); $i++) {
if ($str[$i] === 'O' && rand(0, 1) === 1) {
$str[$i] = 'U';
}
}
echo $str;
Edit :
If you want at least 1 U with same chances for each possibility:
do {
$str ="GOODDAY";
$good = false;
for ($i = 0; $i < strlen($str); $i++) {
if ($str[$i] === 'O' && rand(0, 1) === 1) {
$str[$i] = 'U';
$good = true;
}
}
} while (false === $good);
echo $str;
Related
I am trying to capitalize the first letter of word in php without using ucfirst() function But i am not able do it , but i am struggling with this. Please tell me its answer.
<?php
$str ="the resources of earth make life possible on it";
$str[0] = chr(ord($str[0])-32);
$length = strlen($str);
for($pos=0; $pos<$length; $pos++){
if($str[$pos]==' '){
$str[$pos+1] = chr(ord($str[$pos+1])-32);
}
}
echo $str;
?>
Without using the function ucfirst, you can do it like this:
$firstLetter = substr($word, 0, 1);
$restOfWord = substr($word, 1);
$firstLetter = strtoupper($firstLetter);
$restOfWord = strtolower($restOfWord);
print "{$firstLetter}{$restOfWord}\n";
To do it for each word, use explode(' ', $string) to get an array of words, or preg_split('#\\s+#', $string, -1, PREG_SPLIT_NO_EMPTY) for better results.
I would advise against just subtracting 32 from the first character of the next word:
you do not know it is a letter
you do not know it isn't already capitalized
you do not know it exists
you do not know it is not another space
At the very least check that its ord() value lies between ord('A') and ord('Z').
To do this all without case-changing functions, you'd do
$text = implode(' ',
array_map(
function($word) {
$firstLetter = substr($word, 0, 1);
if ($firstLetter >= 'a' && $firstLetter <= 'z') {
$firstLetter = chr(ord($firstLetter)-32);
}
$restOfWord = substr($word, 1);
$len = strlen($restOfWord);
for ($i = 0; $i < $len; $i++) {
if ($restOfWord[$i] >= 'A' && $restOfWord[$i] <= 'Z') {
$restOfWord[$i] = chr(ord(restOfWord[$i])+32);
}
}
return $firstLetter . $restOfWord;
},
preg_split('#\\s+#', $originalText, -1, PREG_SPLIT_NO_EMPTY)
)
);
as such...
$str ="the resources of earth make life possible on it";
$words=array_map(static fn($a) => ucfirst($a), explode(' ', $str));
echo implode(' ', $words);
with ord and chr
$ordb=ord('b'); //98
$capitalB=chr(98-32); //B
$ordA=ord('a'); //97
$caiptalA=chr(97-32); //A
//so
function capitalize(string $word)
{
$newWord = '';
$previousCharIsEmpty = true;
$length = strlen($word);
for ($a = 0; $a < $length; $a++) {
if ($word[$a] === ' ') {
$newWord .= ' ';
$previousCharIsEmpty = true;
} else {
if ($previousCharIsEmpty === true) {
$ord = ord($word[$a]);
$char = chr($ord - 32);
$newWord .= $char;
$previousCharIsEmpty = false;
} else {
$newWord .= $word[$a];
}
$previousCharIsEmpty = false;
}
return $newWord;
}
$word = 'this for example by dilo abininyeri';
echo capitalize($word);
and output
This For Example By Dilo Abininyeri
We cannot do this without any function. We have to use some function. Like you have applied the for-loop and for strlen function.
<?php
$str ="the resources of earth make life possible on it";
$str[0] = chr(ord($str[0])-32);
$length = strlen($str);
for($pos=0; $pos<$length; $pos++){
if($str[$pos]==' '){
$str[$pos+1] = chr(ord($str[$pos+1])-32);
}
}
echo $str;
?>
I have a string like $str.
$str = "00016cam 321254300022cam 321254312315300020cam 32125433153";
I want to split it in array like this. The numbers before 'cam' is the string length.
$splitArray = ["00016cam 3212543", "00022cam 3212543123153", "00020cam 32125433153"]
I have tried following code:
$lengtharray = array();
while ($str != null)
{
$sublength = substr($str, $star, $end);
$star += (int)$sublength; // echo $star."<br>"; // echo $sublength."<br>";
if($star == $total)
{
exit;
}
else
{
}
array_push($lengtharray, $star); // echo
print_r($lengtharray);
}
You can try this 1 line solution
$str = explode('**', preg_replace('/\**cam/', 'cam', $str)) ;
If your string doesn't contain stars then I'm afraid you need to write a simple parser that will:
take characters from the left until it's not numeric
do substr having the length
repeat previous steps on not consumed string
<?php
$input = "00016cam 321254300022cam 321254312315300020cam 32125433153";
function parseArray(string $input)
{
$result = [];
while ($parsed = parseItem($input)) {
$input = $parsed['rest'];
$result[] = $parsed['item'];
}
return $result;
}
function parseItem(string $input)
{
$sLen = strlen($input);
$len = '';
$pos = 0;
while ($pos < $sLen && is_numeric($input[$pos])) {
$len .= $input[$pos];
$pos++;
}
if ((int) $len == 0) {
return null;
}
return [
'rest' => substr($input, $len),
'item' => substr($input, 0, $len)
];
}
var_dump(parseArray($input));
this code works for me. hope helps.
$str = "**00016**cam 3212543**00022**cam 3212543123153**00020**cam 32125433153";
$arr = explode("**", $str);
for ($i=1; $i < sizeof($arr); $i=$i+2)
$arr_final[]=$arr[$i].$arr[$i+1];
I was asked this question in a recent interview.
A string contains a-z, A-Z and spaces. Sort the string so that all lower cases are at the beginning, spaces in the middle and upper cases at the end. Original order among lower and upper cases needs to remain the same. This is what I came up with:
$str = "wElComE to CaLiFOrNiA";
$lowercase ="";
$uppercase="";
$spaces="";
for ($i=0 ; $i <= strlen($str)-1 ; $i++)
{
if ($str[$i] <= 'z' && $str[$i] >= 'a' )
{
$lowercase .=$str[$i];
}
else if (($str[$i] <= 'Z' && $str[$i] >= 'A'))
{
$uppercase .=$str[$i];
}
else
{
$spaces.=$str[$i];
}
}
echo $lowercase.$spaces.$uppercase;
input: wElComE to CaLiFOrNiA
output: wlomtoairi ECECLFONA
I'm wondering if there are better ways to do this? And there are 2 spaces in the input string, and the output shows only one space. The complexity of this is O(N) right.
Any ideas?
I'm sure there are many ways to do this. You could do it with regular expressions..
$str = "wElComE to CaLiFOrNiA";
preg_match_all('~([a-z])~', $str, $lowercase);
preg_match_all('~([A-Z])~', $str, $uppercase);
preg_match_all('~(\h)~', $str, $spaces);
echo implode('', $lowercase[1]) . implode('', $spaces[1]) . implode('', $uppercase[1]);
Output:
wlomtoairi ECECLFONA
When you say better are you referring to performance, readability, or something else?
Second regex approach:
$str = "wElComE to CaLiFOrNiA";
echo preg_replace('~[^a-z]~', '', $str) . preg_replace('~[^\h]~', '', $str) . preg_replace('~[^A-Z]~', '', $str);
I think your solution is pretty OK, but if you are into micro-optimization you could make some minor changes. The following is faster than the regular expression solutions above (benchmark run 10000 times) at least on my system:
$str = "wElComE to CaLiFOrNiA";
$lowercase = "";
$uppercase = "";
$spaces = "";
$end = strlen($str); // Calculate length just once
for ($i = 0; $i < $end; $i++) {
$c = $str[$i]; // Get $str[$i] once
// We know there are only A-Z, a-z and space chars so we
// only need a greater-than check ('a' > 'A' > ' ')
if ($c >= 'a') {
$lowercase .= $c;
} else if ($c >= 'A') {
$uppercase .= $c;
} else
$spaces .= $c;
}
echo $lowercase . $spaces . $uppercase, PHP_EOL;
function sortString($string)
{
$string_chars = str_split($string);
$output = ['', '', ''];
foreach ($string_chars as $char) {
$output[$char === ' ' ? 1 : ($char === ucfirst($char) ? 2 : 0)] .= $char;
}
return implode('', $output);
}
echo sortString("wElComE to CaLiFOrNiA");
Gives wlomtoairi ECECLFONA
I am using codes like "gjhyYhK", "HJjhkeuJ" etc. But want user to show these codes like:
gj_y__K
HJj__e_J
means code will be edited with "_" at random positions in code.
This will do what you want:
$str = "gjhyYhK";
$len = strlen($str);
$num_to_remove = ceil($len * .4); // 40% removal
for($i = 0; $i < $num_to_remove; $i++)
{
$k = 0;
do
{
$k = rand(1, $len);
} while($str[$k-1] == "_");
$str[$k-1] = "_";
}
print $str . "\n";
If you want more underscores, change the value of $underscores. This will guarantee you get how many underscores you want, so long as you want fewer than the length of the string
Try this:
$string=array(
'gjhyYhK',
'HJjhkeuJ'
);
$arr=array();
foreach ($string as $key=>$value) {
$arr[$key]='';
for ($i=1; $i <=strlen($value); $i++) {
if(rand(0,1)){
$arr[$key].=substr($string[$key],$i,1);
}else{
$arr[$key].='_';
}
}
}
var_dump($arr);
you can try below code to get the functionality what you are looking for
<?php
$string = "gjhyYhK";
$percentage = 40;
$total_length = strlen($string);
$number_of_underscore = floor(($percentage / 100) * $total_length); // I have use floor value, you can use ceil() as well
for ($i = 1; $i <= $number_of_underscore; $i++)
{
$random_position = rand(0, strlen($string) - 1); // get the random position of character to be replaced
if (substr($string, $random_position, 1) !== '_') // check if its already replaced underscore (_)
{
$string = preg_replace("/" . (substr($string, $random_position, 1)) . "/", '_', $string, 1); // here preg_replaced use to replace the character only once, (i.e str_replace() will replace all matching characters)
}
else
{
$i--; // else decrement $i for the loop to run one more time
}
}
echo $string;
?>
let me know if any other help needed
$str = "ADFJ";
$strlen = strlen($str);
$newStr = '';
for ($i = 0; $i < $strlen; $i++) {
if ($i == rand(0, $strlen)) {
$newStr .= '_';
} else {
$newStr .= $str[$i];
}
}
echo $newStr;
This question already has answers here:
Reverse the letters in each word of a string
(6 answers)
Closed 1 year ago.
This task has already been asked/answered, but I recently had a job interview that imposed some additional challenges to demonstrate my ability to manipulate strings.
Problem: How to reverse words in a string? You can use strpos(), strlen() and substr(), but not other very useful functions such as explode(), strrev(), etc.
Example:
$string = "I am a boy"
Answer:
I ma a yob
Below is my working coding attempt that took me 2 days [sigh], but there must be a more elegant and concise solution.
Intention:
1. get number of words
2. based on word count, grab each word and store into array
3. loop through array and output each word in reverse order
Code:
$str = "I am a boy";
echo reverse_word($str) . "\n";
function reverse_word($input) {
//first find how many words in the string based on whitespace
$num_ws = 0;
$p = 0;
while(strpos($input, " ", $p) !== false) {
$num_ws ++;
$p = strpos($input, ' ', $p) + 1;
}
echo "num ws is $num_ws\n";
//now start grabbing word and store into array
$p = 0;
for($i=0; $i<$num_ws + 1; $i++) {
$ws_index = strpos($input, " ", $p);
//if no more ws, grab the rest
if($ws_index === false) {
$word = substr($input, $p);
}
else {
$length = $ws_index - $p;
$word = substr($input, $p, $length);
}
$result[] = $word;
$p = $ws_index + 1; //move onto first char of next word
}
print_r($result);
//append reversed words
$str = '';
for($i=0; $i<count($result); $i++) {
$str .= reverse($result[$i]) . " ";
}
return $str;
}
function reverse($str) {
$a = 0;
$b = strlen($str)-1;
while($a < $b) {
swap($str, $a, $b);
$a ++;
$b --;
}
return $str;
}
function swap(&$str, $i1, $i2) {
$tmp = $str[$i1];
$str[$i1] = $str[$i2];
$str[$i2] = $tmp;
}
$string = "I am a boy";
$reversed = "";
$tmp = "";
for($i = 0; $i < strlen($string); $i++) {
if($string[$i] == " ") {
$reversed .= $tmp . " ";
$tmp = "";
continue;
}
$tmp = $string[$i] . $tmp;
}
$reversed .= $tmp;
print $reversed . PHP_EOL;
>> I ma a yob
Whoops! Mis-read the question. Here you go (Note that this will split on all non-letter boundaries, not just space. If you want a character not to be split upon, just add it to $wordChars):
function revWords($string) {
//We need to find word boundries
$wordChars = 'abcdefghijklmnopqrstuvwxyz';
$buffer = '';
$return = '';
$len = strlen($string);
$i = 0;
while ($i < $len) {
$chr = $string[$i];
if (($chr & 0xC0) == 0xC0) {
//UTF8 Characer!
if (($chr & 0xF0) == 0xF0) {
//4 Byte Sequence
$chr .= substr($string, $i + 1, 3);
$i += 3;
} elseif (($chr & 0xE0) == 0xE0) {
//3 Byte Sequence
$chr .= substr($string, $i + 1, 2);
$i += 2;
} else {
//2 Byte Sequence
$i++;
$chr .= $string[$i];
}
}
if (stripos($wordChars, $chr) !== false) {
$buffer = $chr . $buffer;
} else {
$return .= $buffer . $chr;
$buffer = '';
}
$i++;
}
return $return . $buffer;
}
Edit: Now it's a single function, and stores the buffer naively in reversed notation.
Edit2: Now handles UTF8 characters (just add "word" characters to the $wordChars string)...
My answer is to count the string length, split the letters into an array and then, loop it backwards. This is also a good way to check if a word is a palindrome. This can only be used for regular string and numbers.
preg_split can be changed to explode() as well.
/**
* Code snippet to reverse a string (LM)
*/
$words = array('one', 'only', 'apple', 'jobs');
foreach ($words as $d) {
$strlen = strlen($d);
$splits = preg_split('//', $d, -1, PREG_SPLIT_NO_EMPTY);
for ($i = $strlen; $i >= 0; $i=$i-1) {
#$reverse .= $splits[$i];
}
echo "Regular: {$d}".PHP_EOL;
echo "Reverse: {$reverse}".PHP_EOL;
echo "-----".PHP_EOL;
unset($reverse);
}
Without using any function.
$string = 'I am a boy';
$newString = '';
$temp = '';
$i = 0;
while(#$string[$i] != '')
{
if($string[$i] == ' ') {
$newString .= $temp . ' ';
$temp = '';
}
else {
$temp = $string[$i] . $temp;
}
$i++;
}
$newString .= $temp . ' ';
echo $newString;
Output: I ma a yob