Find all letters not used in a string - php

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;
}

Related

Replace all in a string except of two indexes

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

How to retrieve repeating substrings from a string? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
how to explode even words in string of symbol "-"? for ex.:
$string = 'tshirt-blue-124-tshirt-blue-124-tshirt-blue-124';
or
$string = '333-red-333-red-333-red-333-red';
I need array like this:
$string[0] = 'tshirt-blue-124';
$string[1] = 'tshirt-blue-124';
$string[2] = 'tshirt-blue-124';
or
$string[0] = '333-red';
$string[1] = '333-red';
$string[2] = '333-red';
$string[3] = '333-red';
thanks
If it's always every three elements:
$string = 'tshirt-blue-124-tshirt-blue-124-tshirt-blue-124';
$newArray = array_chunk(explode('-', $string), 3);
array_walk(
$newArray,
function(&$value) {
$value = implode('-', $value);
});
var_dump($newArray);
EDIT
But you must know how many elements in advance:
$splitValue = 2;
$string = '333-red-333-red-333-red-333-red';
$newArray = array_chunk(explode('-', $string), $splitValue);
array_walk(
$newArray,
function(&$value) {
$value = implode('-', $value);
});
var_dump($newArray);
EDIT #2
If you have no idea how many elements that there in a repetition block, then look into the Lempel-Ziv-Welsh (LZW) compression algorithm. It is built on detecting repetitions in strings and utilizing them for compression. You can probably use a Suffix Trie datastructure to simplify the logic.
EDIT #3
As a simplistic approach to trying to identify the split size:
function getSplitSize($string) {
$splitSize = 2;
do {
$tempArray = array_chunk(explode('-', $string), $splitSize);
if ($tempArray[0] == $tempArray[1])
return $splitSize;
++$splitSize;
} while ($splitSize <= count($tempArray));
throw new Exception('No repetition found');
}
function splitStringOnRepetition($string) {
$newArray = array_chunk(explode('-', $string), getSplitSize($string));
array_walk(
$newArray,
function(&$value) {
$value = implode('-', $value);
}
);
return $newArray;
}
$string = 'tshirt-blue-124-tshirt-blue-124-tshirt-blue-124';
$array = splitStringOnRepetition($string);
var_dump($array);
$string = '333-red-333-red-333-red-333-red';
$array = splitStringOnRepetition($string);
var_dump($array);
For advanced yet efficient method, you can use a regular expression matching using preg_match():
$string = 'tshirt-blue-124-tshirt-blue-125-tshirt-blue-126';
$pattern = "/([A-Za-z]*-[A-Za-z]*-[\d]*)-?/";
preg_match_all($pattern, $string, $matches);
echo "<pre>";
print_r($matches[1]);
echo "</pre>";
and it will output:
Array
(
[0] => tshirt-blue-124
[1] => tshirt-blue-125
[2] => tshirt-blue-126
)
you can set the pattern the way you want..
Try with -
$string = 'tshirt-blue-124-tshirt-blue-124-tshirt-blue-124';
$new = explode('-', $string);
$i = 0;
$result = array();
while ($i < count($new)) {
$result[] = $new[$i].'-'.$new[$i+1].'-'.$new[$i+2];
$i += 3;
}
var_dump($result);
you can do something like this
$string = 'tshirt-blue-124-tshirt-blue-124-tshirt-blue-124';
$tmp = explode("-", $string);
while ($tmp) {
$output[] = implode('-', array_splice($tmp, 0, 3));
}
print_r($output);
Explode it
$string = explode("tshirt-", $string);
Now you have to add the value to each Array element
foreach($string as &$v){
$v = "tshirt-" . $v;
$v = rtrim($v, "-");
}
This is a very easy and simple to understand solution.

php substring Issue

I have the following string:
$str = "ABACADAF";
I am using the following code:
$first2 = substr($str, 0, 2);
I want to get the following output:
output => `AB,AC,AD,AF`
(Every two characters separated by comma)
But the result I'm getting is not correct.
I checked the php manual but that is not helping, is there some foreach loop to iterate through all the string characters?
Not tested, but should be something along these lines:
<?php
$string = "ABACADAF";
$split = str_split($string, 2);
$implode = implode(",", $split);
echo $implode;
?>
You are looking for str_split function. You can do like this:
$sResult = join(',', str_split($sData, 2));
Alternatively, you can do it via regex:
$sResult = preg_replace('/(..)(?!$)/', '$1,', $sData);
Here's a function that you can use to output from a foreach. We're finding two capital letter matches and putting them into an array, then we implode that array() to make a string.
<?php
function splitter($string){
preg_match_all('/[A-Z]{2}/', $string, $matches);
$newstring = implode(',',$matches[0]);
return $newstring;
}
$strings = array("ABACADAF","ACABAFAC","AAABAFAD","ACACADAF");
foreach($strings as $string){
echo splitter($string)."\n";
}
?>
Output
AB,AC,AD,AF
AC,AB,AF,AC
AA,AB,AF,AD
AC,AC,AD,AF
If you're running a lot of them (millions of lines) you can use this function instead. It's much quicker.
function splitter($string){
$newstring = substr(chunk_split($string, 2, ','), 0, -1);
return $newstring;
}
You could do it like this or recursively as well.
<?php
for ($i=0; $i< strlen($str); $i=$i+3)
{
$str = substr($str,i,2).",".substr($str,3);
}
echo $str;
?>
I personally prefer the recursive implementation:
<?php
function add_comma($str)
{
return substr($str, 0, 2,).','.add_comma(subtr($str,3));
}
echo add_comma($str);
?>
While this is doable with a for loop, it is cleaner (and maybe faster), and more strait-forward in TomUnite's answer.
But since you asked...
With a for loop you could do it like this:
$withCommas = substr($string, 0, 2);
for($i=0; $i < strlen($string); $i += 2){
$withCommas+= "," . substr($string, $i, $i+2);
}
Here is the solution and Same output of your problem:
I personally tested it :
<?php
$str = "ABACADAF";
$first = substr($str, 0, 2);
$second = substr($str, 2, 2);
$third = substr($str, 4, 2);
$fourth = substr($str, 6, 2);
echo $output = $first.",".$second.",".$third.",".$fourth;
?>

php the best way to split string containing pairs of values

i have a string in the following format:
$str='a1_b1,a2_b2,a3_b3'
where a and b - some positive numbers. i need to split it to get two strings in format:
'a1,a2,a3' and 'b1,b2,b3'
the very primitive way would be:
$temp=explode(',', $str);
$str1='';
$str2='';
for($i=0;$i<count($temp);$i++){
$temp2=explode('_',$temp[$i]);
$str1.=$temp2[0].',';
$str2.=$temp2[1].',';
}
is it possible to do it more intelligent then just explode in loop?
Not much different from accepted answer but doing it with fewer code
<?php
$str = 'a1_b1,a2_b2,a3_b3';
$temp=explode(',', $str);
foreach($temp as $tem)
list($str_a[], $str_b[])=explode('_',$tem);
$str1 = implode(',', $str_a);
$str2 = implode(',', $str_b);
Probably the easiest way (which also happens to use the least amount of code and no loops) is to make use of PHP's parse_str() function:
// Assuming $str = 'a1_b1,a2_b2,a3_b3'
$str = str_replace([',', '_'], ['&', '='], $str);
parse_str($str, $arr);
// Your key/value pairs are now in $arr
$keys = implode(',', array_keys($arr));
$values = implode(',', array_values($arr));
Of course, parse_str() expects the standard foo=bar&baz=boz format, so if possible, you should use that format instead of foo_bar,baz_boz to save yourself a step. But, if that's not possible, then you can simply use str_replace() like I did above to make the appropriate substitutions.
Note: I used PHP 5.4 short array syntax [...]. If you're using < PHP 5.4, change it to array(...) instead.
The best way would be to organize the formatting of the string so that it doesnt come to this stage where you need to do this. But I'm assuming that you cant do that, therefore posting this question here,
What you did is a good way to do this unless you want to use regex.
$str = 'a1_b1,a2_b2,a3_b3' ;
$exp = explode(',', $str);
$a = array();
$b = array();
foreach($exp as $i)
{
$sep = explode('_', $i);
$a[] = $sep[0];
$b[] = $sep[1];
}
// at this point a and b are arrays so if you want to do better things to the data
// you can use arrays instead of manually concatenating the items with commas
$a_str = implode(',', $a); // a1,a2,a2
$b_str = implode(',', $b); // b1,b2,b2
$temp=explode(',', $str);
$str1='';
$str2='';
$str_a = array();
$str_b = array();
for($i=0;$i<count($temp);$i++){
$temp2=explode('_',$temp[$i]);
$str_a[]=$temp2[0];
$str_b[]=$temp2[1];
}
$str1 = implode(',', $str_a);
$str2 = implode(',', $str_b);
Oh, this is nothing more intelligent...
I can't really think of a better way of doing it. The best thing would be to not get in a situation where you need to do this in the first place but what can we do?
Just to provide another (not better) way of doing the same thing, you can use strtok.
$str='a1_b1,a2_b2,a3_b3';
$tok = strtok($str, "_,");
$i = 0;
$a = array();
$b = array();
while ($tok !== false) {
if ($i++ %2) $b[] = $tok;
else $a[] = $tok;
$tok = strtok("_,");
}
echo implode(',', $a); //a1,a2,a3
echo implode(',', $b); //b1,b2,b3
Your way is more clear and easier to understand, so I'd just stick with it.
Assuming PHP >= 5.3.0:
$str = 'a1_b1,a2_b2,a3_b3';
$array = array_map(function($n) { return explode("_", $n); }, explode(",", $str));
$aString = implode(",", array_map(function($n) { return $n[0]; }, $array));
$bString = implode(",", array_map(function($n) { return $n[1]; }, $array));
var_dump($aString);
var_dump($bString);
Output:
string 'a1,a2,a3' (length=8)
string 'b1,b2,b3' (length=8)
Still looping strictly speaking, but fancier :)
$str = 'a1_b1,a2_b2,a3_b3' ;
$arr = preg_split("/[\s,_]/" , $str);
$str1 = $str2 = '';
for($i=0; $i<count($arr); $i++) {
$str1 .= $arr[$i] ;
if(isset($arr[$i+1]))
$str2 .= $arr[$i+1];
if(isset($arr[$i+2])) {
$str1 .= ',';
$str2 .= ',';
}
$i++;
}

Longest word in a string

How can I get the longest word in a string?
Eg.
$string = "Where did the big Elephant go?";
To return "Elephant"
Loop through the words of the string, keeping track of the longest word so far:
<?php
$string = "Where did the big Elephant go?";
$words = explode(' ', $string);
$longestWordLength = 0;
$longestWord = '';
foreach ($words as $word) {
if (strlen($word) > $longestWordLength) {
$longestWordLength = strlen($word);
$longestWord = $word;
}
}
echo $longestWord;
// Outputs: "Elephant"
?>
Can be made a little more efficient, but you get the idea.
Update: Here is another even shorter way (and this one is definitely new ;)):
function reduce($v, $p) {
return strlen($v) > strlen($p) ? $v : $p;
}
echo array_reduce(str_word_count($string, 1), 'reduce'); // prints Elephant
Similar as already posted but using str_word_count to extract the words (by just splitting at spaces, punctuation marks will be counted too):
$string = "Where did the big Elephant go?";
$words = str_word_count($string, 1);
function cmp($a, $b) {
return strlen($b) - strlen($a);
}
usort($words, 'cmp');
print_r(array_shift($words)); // prints Elephant
How about this -- split on spaces, then sort by the string length, and grab the first:
<?php
$string = "Where did the big Elephant go?";
$words = explode(' ', $string);
usort($words, function($a, $b) {
return strlen($b) - strlen($a);
});
$longest = $words[0];
echo $longest;
Edit If you want to exclude punctuation, for example: "Where went the big Elephant?", you could use preg_split:
$words = preg_split('/\b/', $string);
Here is another solution:
$array = explode(" ",$string);
$result = "";
foreach($array as $candidate)
{
if(strlen($candidate) > strlen($result))
$result = $candidate
}
return $result;
This is a quite useful function when dealing with text so it might be a good idea to create a PHP function for that purpose:
function longestWord($txt) {
$words = preg_split('#[^a-z0-9áéíóúñç]#i', $txt, -1, PREG_SPLIT_NO_EMPTY);
usort($words, function($a, $b) { return strlen($b) - strlen($a); });
return $words[0];
}
echo longestWord("Where did the big Elephant go?");
// prints Elephant
Test this function here: http://ideone.com/FsnkVW
A possible solution would be to split the sentence on a common separator, such as spaces, and then iterate over each word, and only keep a reference to the largest one.
Do note that this will find the first largest word.
<?php
function getLargestWord($str) {
$strArr = explode(' ', $str); // Split the sentence into an word array
$lrgWrd = ''; // initial value for comparison
for ($i = 0; $i < count($strArr); $i++) {
if (strlen($strArr[$i]) > strlen($lrgWrd)) { // Word is larger
$lrgWrd = $strArr[$i]; // Update the reference
}
}
return $lrgWrd;
}
// Example:
echo getLargestWord('Where did the big Elephant go?');
?>
$string ='Where did the big Elephant';
function longestWord($str) {
$str.=" ";
$ex ="";
$max ="";
for($i = 0; $i < strlen($str); $i++)
{
if($str[$i]==" ")
{
if(strlen($ex) > strlen($max))
$max = $ex;
$ex ="";
}else
{
$ex.=$str[$i];
}
}
return $max;
}
echo longestWord($string);

Categories