What is the preferred way of separating two integers? - php

I have variables of form like:
$x = "1-15"
$y = "2-18"
etc.
I need to extract the first and second integer as separate variables.
For example:
if $x = "1-15", return values should be $z = 1 and $w = 15.
I know that It would be possible to do this with regex, but from what I've heard, it should be avoided if possible.
What then would be the "fastest" way of achieving this?

If you are sure this is the format, you can split the string (assuming it is a string, and not literally what you wrote).
Splitting is done with explode in php:
http://php.net/manual/en/function.explode.php
$x = "1-15"; //assuming it is indeed a string
list($z, $w) = explode('-', $x);

Using explode is a better option, If you want to go with regex, Hope this solution will be okay.
Regex: ^\s*(\d+)\s*\-\s*(\d+)\s*$
1. ^\s*(\d+)\s*\-\s*(\d+)\s*$ This will match digits - digits pattern, this will take care of spaces as well.
Try this code snippet here
<?php
$x = '1-15';
extract(getVariables($x));
echo $z;
echo $w;
function getVariables($x)
{
preg_match("/^\s*(\d+)\s*\-\s*(\d+)\s*$/", $x,$matches);
return array("z"=>$matches[1],"w"=>$matches[2]);
}

Related

Is there any manual method other than "str_repeat" to repeat the string?

I mean if we give 3, b as parameters passed into function, it should return "bbb" by using loops.
I've tried some code, but I do not want to post it because it might look crazy for a well-versed developer. I can provide you links, this question has been asked in an interview, mainly they want it to be computed in C or C++. Since I am a PHP practitioner, I am curious to know it is possible in PHP. Below is the link (ROUND 2: SIMPLE CODING(3 hours))
https://www.geeksforgeeks.org/zoho-interview-set-3-campus/
A PHP function to do that would probably look like this:
function string_repeat($num, $string)
{
$result = "";
for ($x = 0; $x < $num; $x++) {
$result .= $string;
}
return $result;
}
So calling echo string_repeat(3, 'b'); would output:
bbb
One way would be to keep around a "dummy" string, of sufficient length to be longer than any string you want to generate. Then, we can use preg_replace to replace each character with whatever the input is. Finally, we can substring that replace string to the desired length.
$dummy = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$length = 3;
$dummy = preg_replace('/./', 'b', $dummy);
$output = substr($dummy, 0, $length);
echo $output;
This prints:
bbb
You could wrap this into a helper function, if you really wanted to do that. Note that internally the regex engine is most likely doing some looping of its own, so we are not really freeing ourselves from looping, just hiding it from the current context.

Count elements inside concatenated string

Example : string="abc,def,rst,xyz"
Output Should be 4
Is there a function that will count the number of values inside a concatenated string without the need for looping.
Thanks
You could use explode which creates an array with the comma as delimeter. No looping needed here.
$string = "abc,def,rst,xyz";
$ex = explode(",",$string);
$amount = count($ex);
//Will return 4
echo $amount;
If you always have a string like abc,def,rst,xyz, you could do something like :
echo substr_count('abc,def,rst,xyz', ',') + 1;
Of course, this is assuming you have a well-formatted string. It won't work with strings like :
'abc,def,rst,'
',def,rst,xyz'
'abc,,rst,xyz'
// And so on...
Try with
$count = substr_count($yourString, ',') + 1;
You are looking for substr_count()
Use it like: $count = substr_count($myString, ",")+1;
But couldn't the strings themselves contain a comma?
You should probably look into the csv functions, such as: str_getcsv() and then do count() on it.

How to change order of substrings inside a larger string?

This is fairly confusing, but I'll try to explain as best I can...
I've got a MYSQL table full of strings like this:
{3}12{2}3{5}52
{3}7{2}44
{3}15{2}2{4}132{5}52{6}22
{3}15{2}3{4}168{5}52
Each string is a combination of product options and option values. The numbers inside the { } are the option, for example {3} = Color. The number immediately following each { } number is that option's value, for example 12 = Blue. I've already got the PHP code that knows how to parse these strings and deliver the information correctly, with one exception: For reasons that are probably too convoluted to get into here, the order of the options needs to be 3,4,2,5,6. (To try to modify the rest of the system to accept the current order would be too monumental a task.) It's fine if a particular combination doesn't have all five options, for instance "{3}7{2}44" delivers the expected result. The problem is just with combinations that include option 2 AND option 4-- their order needs to be switched so that any combination that includes both options 2 and 4, the {4} and its corresponding value comes before the {2} and it's corresponding value.
I've tried bringing the column into Excel and using Text to Columns, splitting them up by the "{" and "}" characters and re-ordering the columns, but since not every string yields the same number of columns, the order gets messed up in other ways (like option 5 coming before option 2).
I've also experimented with using PHP to explode each string into an array (which I thought I could then re-sort) using "}" as the delimiter, but I had no luck with that either because then the numbers blend together in other ways that make them unusable.
TL;DR: I have a bunch of strings like the ones quoted above. In every string that contains both a "{2}" and a "{4}", the placement of both of those values needs to be switched, so that the {4} and the number that follows it comes before the {2} and the number that follows it. In other words:
{3}15{2}3{4}168{5}52
needs to become
{3}15{4}168{2}3{5}52
The closest I've been able to come to a solution, in pseudocode, would be something like:
for each string,
if "{4}" is present in this string AND "{2}" is present in this string,
take the "{4}" and every digit that follows it UNTIL you hit another "{" and store that substring as a variable, then remove it from the string.
then, insert that substring back into the string, at a position starting immediately before the "{2}".
I hope that makes some kind of sense...
Is there any way with PHP, Excel, Notepad++, regular expressions, etc., that I can do this? Any help would be insanely appreciated.
EDITED TO ADD: After several people posted solutions, which I tried, I realized that it would be crucial to mention that my host is running PHP 5.2.17, which doesn't seem to allow for usort with custom sorting. If I could upvote everyone's solution (all of which I tried in PHP Sandbox and all of which worked), I would, but my rep is too low.
How would something like this work for you. The first 9 lines just transform your string into an array with each element being an array of the option number and value. The Order establishes an order for the items to appear in and the last does a usort utilizing the order array for positions.
$str = "{3}15{2}2{4}132{5}52{6}22";
$matches = array();
preg_match_all('/\{([0-9]+)\}([0-9]+)/', $str, $matches);
array_shift($matches);
$options = array();
for($x = 0; $x < count($matches[0]); $x++){
$options[] = array($matches[0][$x], $matches[1][$x]);
}
$order = [3,4,2,5,6];
usort($options, function($a, $b) use ($order) {
return array_search($a[0], $order) - array_search($b[0], $order);
});
To get you data back into the required format you would just
$str = "";
foreach($options as $opt){
$str.="{".$opt[0]."}".$opt[1];
}
On of the bonuses here is that when you add a new options type inserting adjusting the order is just a matter of inserting the option number in the correct position of the $order array.
First of all, those options should probably be in a separate table. You're breaking all kinds of normalization rules stuffing those things into a string like that.
But if you really want to parse that out in php, split the string into a key=>value array with something like this:
$options = [];
$pairs = explode('{', $option_string);
foreach($pairs as $pair) {
list($key,$value) = explode('}', $pair);
$options[$key] = $value;
}
I think this will give you:
$options[3]=15;
$options[2]=3;
$options[4]=168;
$options[5]=52;
Another option would be to use some sort of existing serialization (either serialize() or json_encode() in php) instead of rolling your own:
$options_string = json_encode($options);
// store $options_string in db
then
// get $options_string from db
$options = json_decode($options_string);
Here's a neat solution:
$order = array(3, 4, 2, 5, 6);
$string = '{3}15{2}3{4}168{5}52';
$split = preg_split('#\b(?={)#', $string);
usort($split, function($a, $b) use ($order) {
$a = array_search(preg_replace('#^{(\d+)}\d+$#', '$1', $a), $order);
$b = array_search(preg_replace('#^{(\d+)}\d+$#', '$1', $b), $order);
return $a - $b;
});
$split = implode('', $split);
var_dump($split);

Need every permutation of capitalized letters in php

I want to build an array in php that contains every possible capitalization permutation of a word. so it would be (pseudocode)
function permutate($word){
for ($i=0; $i<count($word); $i++){
...confused here...
array_push($myArray, $newWord)
}
return $myArray;
}
So say I put in "School" I should get an array back of
{school, School, sChool, SCHool, schOOl, ... SCHOOL}
I know of functions that capitalize the string or the first character, but I am really struggling with how to accomplish this.
This should do it for you:
function permute($word){
if(!$word)
return array($word);
$permutations = array();
foreach(permute(substr($word, 1)) as $permutation){
$lower = strtolower($word[0]);
$permutations[] = $lower . $permutation;
$upper = strtoupper($word[0]);
if($upper !== $lower)
$permutations[] = $upper . $permutation;
}
return $permutations;
}
Codepad Demo
However, for your particular use case there may be a better solution. As there are 2^n permutations for a string of length n. It will be infeasible to run this (or even to generate all those strings using any method at all) on a much longer string.
In reality you should probably be converting strings to one particular case before hashing them, before storing them in the database, if you want to do case-insensitive matching.

PHP: Compare the start of two strings

I am wondering if there is a simple way to, in PHP, compare two strings and returns the amount of characters they have in common from the start of the string.
An example:
$s1 = "helloworld";
$s1 = "hellojohn";
These two strings both start with 'hello', which means that both strings have the first 5 characters in common. '5' is the value I'd like to recieve when comparing these two strings.
Is there a computationally fast way of doing this without comparing both strings as arrays to eachother?
function commonChars($s1, $s2) {
$IMAX = min(strlen($s1), strlen($s2));
for($i = 0; $i < $IMAX; $i++)
if($s2[i] != $s1[i]) break;
return $i;
}
If the strings are really big, then I would write my own binary search. Something similar to this totally untested code that I just dreamed up.
function compareSection($start, $end, $string1, $string2) {
$substr1 = substr($string1, $start, $end-$start);
$substr2 = substr($string2, $start, $end-$start);
if ($substr1 == $substr2) return $end;
if ($firstMatches = compareSection(0, $end/2, $substr1, $substr2)) {
return $start + $firstMatches;
if ($lastMatches = compareSection($end/2, $end, $substr, $substr2)) {
return $start+$lastMatches;
}
}
If it's the similarity of the strings you wish to get and not just the actual number of identical characters, there are two functions for that:strcmp and levenshtein. Maybe they suit your goal more than what you asked for in this question.
From my knowledge, I don't think there is a built in function for something like this. Most likely, you will have to make your own.
Shouldn't be too hard. Just loop both strings by index by index until you don't find a match that doesn't match. However far you got is the answer.
Hope that helps!

Categories