I have string as following:
$str = "Q1-Q4,A3-A6,S9-S11";
I need to replace the hyphen-separated substrings with a comma-separated string containing all values that exist within the range.
Desired output is Q1,Q2,Q3,Q4,A3,A4,A5,A6,S9,S10,S11
Q1,Q2,Q3,Q4,A3,A4,A5,A6,S9,S10,S11
|---^^^---| |---^^^---| |---^^---|
Q1-Q4 A3-A6 S9-S11
This should get you going. This separates the sequences, adds in extra items and returns all of this as an array you can conveniently use.
$str = "Q1-Q4,A3-A6,S9-S11";
$ranges = explode (',', $str);
$output = [];
foreach ($ranges as $range) {
$items = explode ('-', $range );
$arr = [];
$fillin = [];
$letter = preg_replace('/[^A-Z]/', '', $items[0]);
$first = preg_replace('/[^0-9]/', '', $items[0]);
$last = preg_replace('/[^0-9]/', '', end($items));
for($i = $first; $i-1 < $last; $i++) {
$fillin[] = $letter . $i;
}
$output[] = $fillin;
}
var_dump( $output );
exit;
This is the kind of task that preg_replace_callback() is perfect for.
Match the range expressions, then create an array of values that fall within the range, implode that temporary attay with commas, and finally use that new string to replace the original range expression.
Code: (Demo)
$str = "Q1-Q4,A3-A6,S9-S11";
echo preg_replace_callback(
'/([A-Z]+)(\d+)-\1(\d+)/',
fn($m) => implode(
',',
array_map(
fn($i) => $m[1] . $i,
range($m[2], $m[3])
)
),
$str
);
// Q1,Q2,Q3,Q4,A3,A4,A5,A6,S9,S10,S11
Related
I want to define two new variables as the longest strings from a given string. if the string does not contain any dashes, just choose it for both.
Example:
$orig=`welcome-to-your-world`
$s1=`welcome`
$s2=`world`
$orig=`welcome-to-your-holiday`
$s1=`welcome` // order not important
$s2=`holiday`// order not important
$orig=`welcome`
$s1=`welcome`
$s2=`welcome`
Solution with explode and sorting result array by length of words:
$orig = 'welcome-to-your-world';
$parts = explode('-', $orig);
if (1 < count($parts)) {
usort($parts, function($a, $b) { return strlen($a) < strlen($b); });
$s1 = array_shift($parts);
$s2 = array_shift($parts);
} else {
$s1 = $s2 = $orig;
}
echo $s1 . PHP_EOL . $s2;
Fiddle here.
It seems like your string is in dash-case (words in lower case separated by dashes).
So, you can do the following:
// convert origin in an array
$origin_array = explode("-", $origin);
//retrivies the first element from array
$s1 = '';
$s2 = '';
// get the longest string
foreach($origin_array as $word) {
if(strlen($word) > strlen($s1)) {
$s1 = $word;
}
}
// remove the longest word from the array
$origin_array = array_diff($origin_array, [$s1]);
// get the second longest string
foreach($origin_array as $word) {
if(strlen($word) > strlen($s2)) {
$s2 = $word;
}
}
I think that solves your problem. Hope that helps!
Note: This method is not efficient because it runs foreach twice. The other answer is better if you care about performance.
$orig = 'welcome-to-your-world';
$array = explode('-', $orig);
$lengths = array_map('strlen', $array);
$s1key = array_search(max($lengths), $lengths);
$s1 = $array[$s1key];
unset ($array[$s1key], $lengths[$s1key]);
$s2key = array_search(max($lengths), $lengths);
$s2 = $array[$s2key];
I am trying to extract a string in php and convert them to comma separated strings
Here are some sample string I am working with and the results I need:
input :
G1_C2_S3_T5 or G4_C5_S4_T7_I6_H3
Result must be :
G1,G1_C2,G1_C2_S3,G1_C2_S3_T5
or
G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3
Input length can be dynamic for comma separation
Is this correct :
$arr = explode("_", $string, 2);
$first = $arr[0];
How can i do that in php?
Something like this should work, $string is the string you are working with
//explode by underscore
$parts = explode('_', $string);
$c = [];
//do until nothing else to pop from array
while (!empty($parts)) {
$c[] = implode('_', $parts);
//will pop element from end of array
array_pop($parts);
}
//reverse
$c = array_reverse($c);
//glue it with comma
echo implode(',', $c);
You should notice that the number of underscore-separated values in your initial string e.g. G4_C5_S4_T7_I6_H3 (6) is equal to the number of comma-separated values in your desired string e.g. G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3 (6). So we'll use this number in our first loop $end = count($parts).
$str = "G4_C5_S4_T7_I6_H3";
$newstr = '';
$parts = explode('_', $str);
$comma = '';
for ($i = 0, $end = count($parts); $i < $end; $i++) {
$newstr .= $comma;
$underscore = '';
// build underscore-separated value
// index i is used to indicate up which value to stop at for each iteration
for ($j = 0; $j <= $i; $j++) {
$newstr .= $underscore . $parts[$j];
// set underscore after the first iteration of the loop
$underscore = '_';
}
// set comma after the first iteration of the loop
$comma = ',';
}
echo $newstr; // G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3
The explosion is easy:
$parts = explode('_', $string);
Now you get a $parts array like [ 'G1', 'C2', 'S3', 'T5' ].
You want to convert this to an array so that each item is the concatenation of that item and every other item before it:
$prev = [ ];
array_walk(
$parts,
function(&$value) use (&$prev) {
$prev[] = $value;
$value = implode('_', $prev);
}
);
Now $parts holds the elements:
print implode(', ', $parts);
yields
G1, G1_C2, G1_C2_S3, G1_C2_S3_T5
Let's say i have the following string: $test ='abcd.gdda<fsa>dr';
And the following array: $array = array('<','.');
How can i find the positions of the characters that are elements in the $array array?
(fastest way possible) and then store and remove them (without leaving NULL values at that specific index)?
Ps. I know that i could use strpos() to check for each element but that would output something like: 9, 5 because the '<' symbol is searched for before the '.' element and that causes the function to believe that the '<' is before '.' in the string. I tried combining this with the sort() function...but i does not work as expected... (it outputs some NULL positions...)
Works with both strings and characters:
<?php
$test ='abcda.gdda<fsa>dr';
$array = array('<', '.', 'dr', 'a'); // not also characters but strings can be used
$pattern = array_map("preg_quote", $array);
$pattern = implode("|", $pattern);
preg_match_all("/({$pattern})/", $test, $matches, PREG_OFFSET_CAPTURE);
array_walk($matches[0], function(&$match) use (&$test)
{
$match = $match[1];
});
$test = str_replace($array, "", $test);
print_r($matches[0]); // positions
echo $test;
Output:
Array
(
[0] => 0
[1] => 4
[2] => 5
[3] => 9
[4] => 10
[5] => 13
[6] => 15
)
bcdgddfs>
Find all positions, store them in array:
$test = 'abcd.gdda<fsa>dr<second . 111';
$array = array('<','.');
$positions = array();
foreach ($array as $char) {
$pos = 0;
while ($pos = strpos($test, $char, $pos)) {
$positions[$char][] = $pos;
$pos += strlen($char);
}
}
print_r($positions);
echo str_replace($array, '', $test);
demo
Here is one possible solutions, depending on every searching element being a single character.
$array = array(',', '.', '<');
$string = 'fdsg.gsdfh<dsf<g,gsd';
$search = implode($array); $last = 0; $out = ''; $pos = array();
foreach ($array as $char) $pos[$char] = array();
while (($len = strcspn($string, $search)) !== strlen($string)) {
$last = ($pos[$string[$len]][] = $last + $len) + 1;
$out .= substr($string, 0, $len);
$string = substr($string, $len+1);
}
$out.=$string;
Demo: http://codepad.org/WAtDGr7p
EDIT:
PHP has an inbuild function for that
str_replace($array, "", $test);
ORIGINAL ANSWER:
Here is how I would do it:
<?php
$test ='abcd.gdda<fsa>dr';
$array = array('<','.');
foreach($array as $delimiter) {
// For every delimiter explode the text into array and the recombine it
$exploded_array = explode($delimiter, $test);
$test = implode("", $exploded_array);
}
?>
There are faster ways to do it (you will gain some microseconds) but why would you use php if you wanted speed :)
I mostly prefer simplicity.
strtr($str, ['<' => '', '.' => '']);
This will probably outperform anything else, because it doesn't require you to iterate over anything in PHP.
I have a comma delimited string and want the first 100 entries (not including the 100th comma) as a single string.
So for example if I had the string
a,b,c,d,e,f,g
And the problem was get the first 3 entries, the desired result string would be
a,b,c
Using explode/implode:
$str = 'a,b,c,d,e,f,g';
$temp1 = explode(',',$str);
$temp2 = array_slice($temp1, 0, 3);
$new_str = implode(',', $temp2);
Using regex:
$new_str = preg_replace('/^((?:[^,]+,){2}[^,]+).*$/','\1',$str);
try php's explode() function.
$string_array = explode(",",$string);
Loop through the array to get the values you want:
for($i = 0; $i < sizeof($string_array); $i++)
{
echo $string_array[$i];//display values
}
You can do so by finding the 100th delimiter:
$delimiter = ',';
$count = 100;
$offset = 0;
while((FALSE !== ($r = strpos($subject, $delimiter, $offset))) && $count--)
{
$offset = $r + !!$count;
}
echo substr($subject, 0, $offset), "\n";
or similarly tokenize it:
$delimiter = ',';
$count = 100;
$len = 0;
$tok = strtok($subject, $delimiter);
while($tok !== FALSE && $count--)
{
$len += strlen($tok) + !!$count;
$tok = strtok($delimiter);
}
echo substr($subject, 0, $len), "\n";
One way is to split the string after a comma and put the first 100 indexes together (comma-separated).
Before this you have to check if count(array) is greater or smaller than 100.
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]);