Split string into 3 random-length parts - php

I have a string and I want to split it into 3 random-length parts (without caring about string length is the objective) to get 3 strings.
$mystring = "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnBocA==";
When I tried to use str_split(), I always have to manually set the number of character per string.
If I calculate the string length and divide it by 3, sometimes I get non-whole numbers.
$len = strlen($mystring);
$len = $len / 3;
$parts = str_split($mystring, $len);
print_r($parts);

Even if you want random then I assume you still don't want 0 length strings.
I use random values between 1 and string length (minus some, to make sure you don't run out of characters).
$mystring = "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnBocA==";
$len=strlen($mystring);
$parts[] = substr($mystring, 0, $l[] = rand(1,$len-5));
$parts[] = substr($mystring, $l[0], $l[] = rand(1,$len-$l[0]-3));
$parts[] = substr($mystring, array_sum($l));
print_r($parts);
The code grabs parts of the string depending on what the previous random value was.
https://3v4l.org/v4nUF

A more generic solution could look like this:
function split_random_parts($string, $part_count) {
$result = [];
for ($i = 0; $i < $part_count - 1; $i++) {
// Always leave part_count - i characters remaining so that no empty string gets created
$len = rand(1, strlen($string) - ($part_count - $i));
$result[] = substr($string, 0, $len);
$string = substr($string, $len);
}
$result[] = $string;
return $result;
}

Something like this would do it:
$mystring = "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnBocA==";
$part3 = substr($mystring, rand(2,(strlen($mystring)-2)));
$mystring = substr($mystring, 0, (strlen($mystring)-strlen($part3)));
$part2 = substr($mystring, rand(1,(strlen($mystring)-1)));
$mystring = substr($mystring, 0, (strlen($mystring)-strlen($part2)));
$part1 = $mystring;
var_dump($part1, $part2, $part3);
This code would produce results such as:
string(67) "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnB"
string(1) "o"
string(4) "cA=="
string(57) "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyL"
string(5) "XNwbG"
string(10) "l0LnBocA=="
string(31) "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW5"
string(27) "1YWwvZW4vZnVuY3Rpb24uc3RyLX"
string(14) "NwbGl0LnBocA=="
string(5) "aHR0c"
string(23) "HM6Ly93d3cucGhwLm5ldC9t"
string(44) "YW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnBocA=="

I mean you just need to round up the result of length division like:
<?php
$mystring = "The any size string ...";
$len=strlen($mystring);
$chunk=ceil($len/3);
$parts = str_split($mystring , $chunk);
print_r($parts);
Here the fiddle

If you need divide to 3 without random length, may you use str_pad like
$str = 'aHR0cHM6Ly93d3cnVuY3Rpb24uc3RyLXNwbGl0LnBocA==';
$divide = 3;
$char = '*'; // that not used in your string
$add = $divide - strlen($str) % $divide;
$total = strlen($str) + $add;
$str = str_pad($str, $total, $char, STR_PAD_LEFT);
//string(48) "**aHR0cHM6Ly93d3cnVuY3Rpb24uc3RyLXNwbGl0LnBocA=="
$result = str_split($str, $total / $divide );
/*array(3) {
[0]=> string(16) "**aHR0cHM6Ly93d3"
[1]=> string(16) "cnVuY3Rpb24uc3Ry"
[2]=> string(16) "LXNwbGl0LnBocA=="
}*/
keep in mind that strip '*' chars before decode
$result = str_replace('*', '', $result);
Demo

Because your input string contains no whitespace characters, you can use sscanf() with %s placeholders with explicit substring lengths (for the first two substrings) to explode the string on dynamic points.
Code: (Demo)
$mystring = "aHR0cHM6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyLXNwbGl0LnBocA==";
$len = strlen($mystring);
$end_of_first = rand(1, $len - 2);
$end_of_middle = rand(1, $len - $end_of_first - 1);
var_export(sscanf($mystring, "%{$end_of_first}s%{$end_of_middle}s%s"));
For anyone else who might have whitespaces in their input string, you can replace the s with [^~] where the ~ should be a character that is guaranteed to not occur in your string.
For an approach that accommodates a variable number of segments, a decementing loop seems appropriate.
Code: (Demo)
$totalSegments = 4;
$segments = [];
while ($totalSegments) {
--$totalSegments;
$segmentLength = rand(1, strlen($mystring) - $totalSegments);
[$segments[], $mystring] = sscanf($mystring, "%{$segmentLength}s%s");
}
var_export($segments);

Related

Split a string on every nth character and ensure that all segment strings have the same length

I want to split the following string into 3-letter elements. Additionally, I want all elements to have 3 letters even when the number of characters in the inout string cannot be split evenly.
Sample string with 10 characters:
$string = 'lognstring';
The desired output:
$output = ['log','nst','rin','ing'];
Notice how the in late in the inout string is used a second time to make the last element "full length".
Hope this help you.
$str = 'lognstring';
$arr = str_split($str, 3);
$array1= $arr;
array_push($array1,substr($str, -3));
print_r($array1);
$str = 'lognstring';
$chunk = 3;
$arr = str_split($str, $chunk); //["log","nst","rin","g"]
if(strlen(end($arr)) < $chunk) //if last item string length is under $chunk
$arr[count($arr)-1] = substr($str, -$chunk); //replace last item to last $chunk size of $str
print_r($arr);
/**
array(4) {
[0]=>
string(3) "log"
[1]=>
string(3) "nst"
[2]=>
string(3) "rin"
[3]=>
string(3) "ing"
}
*/
Differently from the earlier posted answers that blast the string with str_split() then come back and mop up the last element if needed, I'll demonstrate a technique that will populate the array of substrings in one clean pass.
To conditionally reduce the last iterations starting point, either use a ternary condition or min(). I prefer the syntactic brevity of min().
Code: (Demo)
$string = 'lognstring';
$segmentLength = 3;
$totalLength = strlen($string);
for ($i = 0; $i < $totalLength; $i += $segmentLength) {
$result[] = substr($string, min($totalLength - $segmentLength, $i), $segmentLength);
}
var_export($result);
Output:
array (
0 => 'log',
1 => 'nst',
2 => 'rin',
3 => 'ing',
)
Alternatively, you can prepare the string BEFORE splitting (instead of after).
Code: (Demo)
$extra = strlen($string) % $segmentLength;
var_export(
str_split(
$extra
? substr($string, 0, -$extra) . substr($string, -$segmentLength)
: $string,
$segmentLength
)
);

Want to iterate a string that after each charater there will be a space in PHP

I want to iterate a string in the manner that after each character there should be a space and there will be new string(word) as per the main string character count.
For example
If I put the string "v40eb" as an input. Then Output be something like below.
v 40eb
v4 0eb
v40 eb
v40e b
OR
In Array form like below.
[0]=>v 40eb[1]=>v4 0eb[2]=>v40 eb[3]=>v40e b
I am using PHP.
Thanks
Well, you can divide the process of putting a space into 2 parts.
Get first part of the substring, append a space.
Get second part of the substring and join them together.
Use substr() to get a substring of a string.
Snippet:
<?php
$str = "v40eb";
$result = [];
$len = strlen($str);
for($i=0;$i<$len;++$i){
$part1 = substr($str,0,$i+1);
if($i < $len-1) $part1 .= " ";
$part2 = substr($str,$i+1);
$result[] = $part1 . $part2;
}
print_r($result);
Demo: https://3v4l.org/XGN0a
You could simply loop over the char positions and use substr to get the two parts for each:
$input = 'v40eb';
$combinations = [];
for ($charPos = 1, $charPosMax = strlen($input); $charPos < $charPosMax; $charPos++) {
$combinations[] = substr($input, 0, $charPos) . ' ' . substr($input, $charPos);
}
print_r($combinations);
Demo: https://3v4l.org/EeT1V
$input = 'v40eb';
for($i = 1; $i< strlen($input); $i++) {
$array = str_split($input);
array_splice($array, $i, 0, ' ');
$output[] = implode($array);
}
print_r($output);
Dont forget to check the codec. You might use mb_-prefix to use the multibyte-functions.

php string explode on (-) characters

I have a string something like this:
$string = "small (150 - 160)"
Is there a way I could store 150 in the variable $min and 160 in the variable $max in php?
function minMax($string) {
$digits = explode("-", $string);
return filter_var_array($digits, FILTER_SANITIZE_NUMBER_INT);
}
// $yourString = "small (150 - 160)"
$values = minMax( $yourString );
$min = $values[0]; $max = $values[1];
The function uses explode to remove "-" and create an array. The string to left of "-" is placed in $digits[0] and to right in $digits[1].
PHP filters are then used to remove non integer characters from the array strings. Note I assume you are working with whole numbers. filter_var_array won't work with decimal points but you can use filter_var instead with the FILTER_SANITIZE_NUMBER_FLOAT flag to retain decimals points.
function minMax($string) {
return filter_var($string, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
}
$values = minMax( "small (150 - 160.4)" );
$number = explode("-", $values);
$min = $number[0]; $max = $number[1];
In the decimal example immediately above any "." will be retained. If strings can contain non numeric periods then you will need to remove leadin "."s from your output e.g. if string = "big... (150 - 160.4)" then $min will contain '...150' to prevent leading periods $min = trim($min,'.');.
This PHP script will solve your problem:
$string = "small (150 - 160)";
$tmp = preg_replace("/[^0-9\.]/", " ", $string);
$tmp = trim(preg_replace('/\s+/u', ' ', $tmp));
$tmp = explode(' ', $tmp);
$min = $tmp[0];
$max = $tmp[1];
<?php
$string = "small (150 - 160)";
$string = preg_replace('/[^\d-]/', '', $string); // replace everything not a digit and not a "-" with empty string ('')
list( $min, $max ) = explode('-', $string); // split by "-" and store in $min and $max
var_dump( $min);
var_dump( $max );
Output
string(3) "150"
string(3) "160"
preg_match_all('!\d+!', $string, $matches);
var_dump($matches);

how to get last integer in a string?

I have variables like this:
$path1 = "<span class='span1' data-id=2>lorem ipsum</span>";
$path2 = "<span class='span2' data-id=14>lorem ipsum</span>";
I need to get value of data-id but I think it's not possible in php.
Maybe is possible to get last integer in a string ?
Something like:
$a = $path1.lastinteger(); // 2
$b = $path2.lastinteger(); // 14
Any help?
You could use a simple regex:
/data-id=[\"\']([1-9]+)[\"\']/g
Then you can build this function:
function lastinteger($item) {
preg_match_all('/data-id=[\"\']([1-9]+)[\"\']/',$item,$array);
$out = end($array);
return $out[0];
}
Working DEMO.
The full code:
function lastinteger($item) {
preg_match_all('/data-id=[\"\']([1-9]+)[\"\']/',$item,$array);
$out = end($array);
return $out[0];
}
$path1 = "<span class='span1' data-id=2>lorem ipsum</span>";
$path2 = "<span class='span2' data-id=14>lorem ipsum</span>";
$a = lastinteger($path1); //2
$b = lastinteger($path2); //14
References:
preg_match_all()
end()
Tutorial for regex: tutorialspoint.com
Good tool to create regex: regexr.com
If you'd rather not use a regular expression you can use the DOM API:
$dom = DOMDocument::loadHTML($path2);
echo $dom->getElementsByTagName('span')[0]->getAttribute('data-id');
Depending on how those variables get set, one solution could be to get the integer first and then inject it into the paths:
$dataId = 2;
$path1 = "<span class='span1' data-id='$dataId'>lorem ipsum</span>";
(Note that I added quotes around the data-id value, otherwise your HTML is invalid.)
If you aren't building the strings yourself, but need to parse them, I would not simply get the last integer. The reason is that you might get a tag like this:
<span class='span1' data-id='4'>Happy 25th birthday!</span>
In that case, the last integer in the string is 25, which isn't what you want. Instead, I would use a regular expression to capture the value of the data-id attribute:
$path1 = "<span class='span1' data-id='2'>lorem ipsum</span>";
preg_match('/data-id=\'(\d+)\'/', $path1, $matches);
$dataId = $matches[1];
echo($dataId); // => 2
I think that you should use regex, for example:
<?php
$paths = [];
$paths[] = '<span class=\'span1\' data-id=2>lorem ipsum dolor</span>';
$paths[] = '<span class=\'span2\' data-id=14>lorem ipsum</span>';
foreach($paths as $path){
preg_match('/data-id=([0-9]+)/', $path, $data_id);
echo 'data-id for '.$path.' is '.$data_id[1].'<br />';
}
This will output:
data-id for lorem ipsum dolor is 2
data-id for lorem ipsum is 14
function find($path){
$countPath = strlen($path);
for ($i = 0; $i < $countPath; $i++) {
if (substr($path, $i, 3) == "-id") {
echo substr($path, $i + 4, 1);
}
}}find($path1);
Wrote an appropiate function for this purpose.
function LastNumber($text){
$strlength = strlen($text); // get length of the string
$lastNumber = ''; // this variable will accumulate digits
$numberFound = 0;
for($i = $strlength - 1; $i > 0; $i--){ // for cicle reads your string from end to start
if(ctype_digit($text[$i])){
$lastNumber = $lastNumber . $text[$i]; // if digit is found, it is added to last number string;
$numberFound = 1; // and numberFound variable is set to 1
}else if($numberFound){ // if atleast one digit was found (numberFound == 1) and we find non-digit, we know that last number of the string is over so we break from the cicle.
break;
}
}
return intval(strrev($lastNumber), 10); // strrev reverses last number string, because we read original string from end to start. Finally, intval function converts string to integer with base 10
}
I know this has been answered, but if you really want to get the last int in a line without referring specifically to attributes or tag names, consider using this.
$str = "
asfdl;kjas;lkjfasl;kfjas;lf 999 asdflkasjfdl;askjf
<span class='span1' data-id=2>lorem ipsum</span>
<span class='span2' data-id=14>lorem ipsum</span>
Look at me I end with a number 1234
";
$matches = NULL;
$num = preg_match_all('/(.*)(?<!\d)(\d+)[^0-9]*$/m', $str, $matches);
if (!$num) {
echo "no matches found\n";
} else {
var_dump($matches[2]);
}
It will return an array from a multiline input of the last integers for each line:
array(4) {
[0] =>
string(3) "999"
[1] =>
string(1) "2"
[2] =>
string(2) "14"
[3] =>
string(4) "1234"
}

Add +1 to a string obtained from another site

I have a string I get from a website.
A portion of the string is "X2" I want to add +1 to 2.
The entire string I get is:
20120815_00_X2
What I want is to add the "X2" +1 until "20120815_00_X13"
You can do :
$string = '20120815_00_X2';
$concat = substr($string, 0, -1);
$num = (integer) substr($string, -1);
$incremented = $concat . ($num + 1);
echo $incremented;
For more informations about substr() see => documentation
You want to find the number at the end of your string and capture it, test for a maximum value of 12 and add one if that's the case, so your pattern would look something like:
/(\d+)$/ // get all digits at the end
and the whole expression:
$new = preg_replace('/(\d+)$/e', "($1 < 13) ? ($1 + 1) : $1", $original);
I have used the e modifier so that the replacement expression will be evaluated as php code.
See the working example at CodePad.
This solution works (no matter what the number after X is):
function myCustomAdd($string)
{
$original = $string;
$new = explode('_',$original);
$a = end($new);
$b = preg_replace("/[^0-9,.]/", "", $a);
$c = $b + 1;
$letters = preg_replace("/[^a-zA-Z,.]/", '', $a);
$d = $new[0].'_'.$new[1].'_'.$letters.$c;
return $d;
}
var_dump(myCustomAdd("20120815_00_X13"));
Output:
string(15) "20120815_00_X14"

Categories