I have an Array like this
$first = array("10.2+6","5.3+2.2");
I want to convert it like this
$second = array("10+10+6","5+5+5+2+2");
I also want to print out this such as way
10
10
6
5
5
5
2
2
How can I do this?
You can use this preg_replace_callback function:
$first = array("10.2+6", "5.3+2.2");
$second = preg_replace_callback('/\b(\d+)\.(\d+)\b/', function($m){
$_r=$m[1]; for($i=1; $i<$m[2]; $i++) $_r .= '+' . $m[1] ; return $_r; }, $first);
print_r($second);
Output:
Array
(
[0] => 10+10+6
[1] => 5+5+5+2+2
)
We use this regex /\b(\d+)\.(\d+)\b/ where we match digits before and after DOT separately and capture them in 2 captured groups. Then in callback function we loop through 2nd captured group and construct our output by appending + and 1st captured group.
Here's a solution using regular expressions and various functions. There are many ways to accomplish what you're asking, and this is just one of them. I'm sure this could even be improved upon, but here it is:
$first = array("10.2+5","5.3+2.2");
$second = array();
$pattern = '/(\d+)\.(\d)/';
foreach($first as $item){
$parts = explode('+',$item);
$str = '';
foreach($parts as $part){
if(strlen($str)>0) $str .= '+';
if(preg_match_all($pattern, $part, $matches)){
$str .= implode("+", array_fill(0,$matches[2][$i], $matches[1][$i]));
}else{
$str .= $part;
}
}
$second[] = $str;
}
print_r($second);
Output:
Array
(
[0] => 10+10+5
[1] => 5+5+5+2+2
)
<?php
$first = array("10.2+5","5.3+2");
foreach($first as $term)
{
$second="";
$a=explode("+", $term);
$b=explode(".", $a[0]);
$c=$b[0];
for ($i=0;$i<$b[1];$i++)
$second=$second.$c."+";
echo $second.$a[1]."+";
}
?>
Related
I have SKU numbers imported from a CSV file into SQL DB.
Pattern look like:
55A_3
345W_1+04B_1
128T_2+167T_2+113T_8+115T_8
I am trying to move all the letters in front of the numbers.
like:
A55_3
W345_1+B04_1
T128_2+T167_2+T113_8+T115_8
My best idea how to do it was to search for 345W and so, and to replace it with W345 and so:
$sku = "345W_1+04B_1";
$B_range_num = range(0,400);
$B_range_let = range("A","Z");
then generating the find and replace arrays
$B_find =
$B_replace =
maybe just using str_replace??
$res = str_replace($B_find,$B_replace,$sku);
Result should be for all SKU numbers
W345_1+B04_1
Any ideas?
You can use preg_replace to do this job, looking for some digits, followed by a letters and one of an _ with digits, a + or end of string, and then swapping the order of the digits and letters:
$skus = array('55A_3',
'345W_1+04B_1',
'128T_2+167T_2+113T_8+115T_8',
'55A');
foreach ($skus as &$sku) {
$sku = preg_replace('/(\d+)([A-Z]+)(?=_\d+|\+|$)/', '$2$1', $sku);
}
print_r($skus);
Output:
Array
(
[0] => A55_3
[1] => W345_1+B04_1
[2] => T128_2+T167_2+T113_8+T115_8
[3] => A55
)
Demo on 3v4l.org
Here I defined a method with specific format with unlimited length.
$str = '128T_2+167T_2+113T_8+115T_8';
echo convertProductSku($str);
function convertProductSku($str) {
$arr = [];
$parts = explode('+', $str);
foreach ($parts as $part) {
list($first, $second) = array_pad(explode('_', $part), 2, null);
$letter = substr($first, -1);
$number = substr($first, 0, -1);
$arr[] = $letter . $number . ($second ? '_' . $second : '');
}
return implode('+', $arr);
}
I'm looking to get an array of ID's from the following string.
[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]
Ideally, i'd like to look at this string and get an array of the INT values within images. e.g.
array("3057", "2141", "234");
find images value and explode it to receive array
$str = '[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]';
if (preg_match('/images\s*=\s*\"([^\"]+)\"/', $str, $m)) {
$res = explode(',', $m[1]);
print_r($res);
}
Another solution using explode and strpos functions:
$str = '[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]';
foreach (explode(" ", $str) as $v) {
if (strpos($v, "images=") === 0) {
$result = explode(",", explode('"', $v)[1]);
break; // avoids redundant iterations
}
}
print_r($result);
The output:
Array
(
[0] => 3057
[1] => 2141
[2] => 234
)
Sorry for English is not my mother language, maybe the question title is not quite good. I want to do something like this.
$str = array("Lincoln Crown","Crown Court","go holiday","house fire","John Hinton","Hinton Jailed");
here is an array, "Lincoln Crown" contain "Lincoln" and "Crown", so remove next words, which contains these 2 words, and "Crown Court(contain Crown)" has been removed.
in another case. "John Hinton" contain "John" and "Hinton", so "Hinton Jailed(contain Hinton)" has been removed. the final output should be like this:
$output = array("Lincoln Crown","go holiday","house fire","John Hinton");
for my php skill is not good, it is not simply to use array_unique() array_diff(), so open a question for help, thanks.
I think this might work :P
function cool_function($strs){
// Black list
$toExclude = array();
foreach($strs as $s){
// If it's not on blacklist, then search for it
if(!in_array($s, $toExclude)){
// Explode into blocks
foreach(explode(" ",$s) as $block){
// Search the block on array
$found = preg_grep("/" . preg_quote($block) . "/", $strs);
foreach($found as $k => $f){
if($f != $s){
// Place each found item that's different from current item into blacklist
$toExclude[$k] = $f;
}
}
}
}
}
// Unset all keys that was found
foreach($toExclude as $k => $v){
unset($strs[$k]);
}
// Return the result
return $strs;
}
$strs = array("Lincoln Crown","Crown Court","go holiday","house fire","John Hinton","Hinton Jailed");
print_r(cool_function($strs));
Dump:
Array
(
[0] => Lincoln Crown
[2] => go holiday
[3] => house fire
[4] => John Hinton
)
Seems like you would need a loop and then build a list of words in the array.
Like:
<?
// Store existing array's words; elements will compare their words to this array
// if an element's words are already in this array, the element is deleted
// else the element has its words added to this array
$arrayWords = array();
// Loop through your existing array of elements
foreach ($existingArray as $key => $phrase) {
// Get element's individual words
$words = explode(" ", $phrase);
// Assume the element will not be deleted
$keepWords = true;
// Loop through the element's words
foreach ($words as $word) {
// If one of the words is already in arrayWords (another element uses the word)
if (in_array($word, $arrayWords)) {
// Delete the element
unset($existingArray[$key]);
// Indicate we are not keeping any of the element's words
$keepWords = false;
// Stop the foreach loop
break;
}
}
// Only add the element's words to arrayWords if the entire element stays
if ($keepWords) {
$arrayWords = array_merge($arrayWords, $words);
}
}
?>
As I would do in your case:
$words = array();
foreach($str as $key =>$entry)
{
$entryWords = explode(' ', $entry);
$isDuplicated = false;
foreach($entryWords as $word)
if(in_array($word, $words))
$isDuplicated = true;
if(!$isDuplicated)
$words = array_merge($words, $entryWords);
else
unset($str[$key]);
}
var_dump($str);
Output:
array (size=4)
0 => string 'Lincoln Crown' (length=13)
2 => string 'go holiday' (length=10)
3 => string 'house fire' (length=10)
4 => string 'John Hinton' (length=11)
I can imagine quite a few techniques that can provide your desired output, but the logic that you require is poorly defined in your question. I am assuming that whole word matching is required -- so word boundaries should be used in any regex patterns. Case sensitivity isn't mentioned. I am unsure if only fully unique elements (multi-word strings) should have their words entered into the black list. I'll offer a few snippets, but choosing the appropriate technique will depend on exact logical requirements.
Demo
$output = [];
$blacklist = [];
foreach ($input as $string) {
if (!$blacklist || !preg_match('/\b(?:' . implode('|', $blacklist) . ')\b/', $string)) {
$output[] = $string;
}
foreach(explode(' ', $string) as $word) {
$blacklist[$word] = preg_quote($word);
}
}
var_export($output);
Demo
$output = [];
$blacklist = [];
foreach ($input as $string) {
$words = explode(' ', $string);
foreach ($words as $word) {
if (in_array($word, $blacklist)) {
continue 2;
}
}
array_push($blacklist, ...$words);
$output[] = $string;
}
var_export($output);
And my favorite because it performs fewest iterations in the parent loop, is more compact, and doesn't require the declaration/maintenance of a blacklist array.
Demo
$output = [];
while ($input) {
$output[] = $words = array_shift($input);
$input = preg_grep('~\b(?:\Q' . str_replace(' ', '\E|\Q', $words) . '\E)\b~', $input, PREG_GREP_INVERT);
}
var_export($output);
You can explode each string in the original array and then compare per-words using a loop (comparing each word from one array with each word from another, and if they match, remove the whole array).
array_unique() example
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
output:
Array
(
[a] => green
[0] => red
[1] => blue
)
Source
I have string:
ABCDEFGHIJK
And I have two arrays of positions in that string that I want to insert different things to.
Array
(
[0] => 0
[1] => 5
)
Array
(
[0] => 7
[1] => 9
)
Which if I decided to add the # character and the = character, it'd produce:
#ABCDE=FG#HI=JK
Is there any way I can do this without a complicated set of substr?
Also, # and = need to be variables that can be of any length, not just one character.
You can use string as array
$str = "ABCDEFGH";
$characters = preg_split('//', $str, -1);
And afterwards you array_splice to insert '#' or '=' to position given by array
Return the array back to string is done by:
$str = implode("",$str);
This works for any number of characters (I am using "#a" and "=b" as the character sequences):
function array_insert($array,$pos,$val)
{
$array2 = array_splice($array,$pos);
$array[] = $val;
$array = array_merge($array,$array2);
return $array;
}
$s = "ABCDEFGHIJK";
$arr = str_split($s);
$arr_add1 = array(0=>0, 1=>5);
$arr_add2 = array(0=>7, 1=>9);
$char1 = '#a';
$char2 = '=b';
$arr = array_insert($arr, $arr_add1[0], $char1);
$arr = array_insert($arr, $arr_add1[1] + strlen($char1), $char2);
$arr = array_insert($arr, $arr_add2[0]+ strlen($char1)+ strlen($char2), $char1);
$arr = array_insert($arr, $arr_add2[1]+ strlen($char1)+ strlen($char2) + strlen($char1), $char2);
$s = implode("", $arr);
print_r($s);
There is an easy function for that: substr_replace. But for this to work, you would have to structure you array differently (which would be more structured anyway), e.g.:
$replacement = array(
0 => '#',
5 => '=',
7 => '#',
9 => '='
);
Then sort the array by keys descending, using krsort:
krsort($replacement);
And then you just need to loop over the array:
$str = "ABCDEFGHIJK";
foreach($replacement as $position => $rep) {
$str = substr_replace($str, $rep, $position, 0);
}
echo $str; // prints #ABCDE=FG#HI=JK
This works by inserting the replacements starting from the end of string. And it would work with any replacement string without having to determine the length of that string.
Working DEMO
$arr = array('superman','gossipgirl',...);
$text = 'arbitary stuff here...';
What I want to do is find the first/last occurencing index of each word in $arr within $text,how to do it efficiently in PHP?
What i think you want is array_keys http://uk3.php.net/manual/en/function.array-keys.php
<?php
$array = array("blue", "red", "green", "blue", "blue");
$keys = array_keys($array, "blue");
print_r($keys);
?>
The above example will output:
Array
(
[0] => 0
[1] => 3
[2] => 4
)
echo 'First '.$keys[0] will echo the first.
You can get the last various ways, one way would be to count the elements and then echo last one e.g.
$count = count($keys);
echo ' Last '.$keys[$count -1]; # -1 as count will return the number of entries.
The above example will output:
First 0 Last 4
I think you want:
<?php
$arr = array('superman','gossipgirl',...);
$text = 'arbitary stuff here...';
$occurence_array = array();
foreach ($arr as $value) {
$first = strpos($text, $value);
$last = strrpos($text, $value);
$occurence_array[$value] = array($first,$last);
}
?>
strpos-based methods will tell you nothing about words positions, they only able to find substrings of text. Try regular expressions:
preg_match_all('~\b(?:' . implode('|', $words) . ')\b~', $text, $m, PREG_OFFSET_CAPTURE);
$map = array();
foreach($m[0] as $e) $map[$e[0]][] = $e[1];
this generates a word-position map like this
'word1' => array(pos1, pos2, ...),
'word2' => array(pos1, pos2, ...),
Once you've got this, you can easily find first/last positions by using
$firstPosOfEachWord = array_map('min', $map);
You could do this by using strpos and strrpos together with a simple foreach loop.