I need to create a function which will be able to extract string representations of numbers and return them as integers but I'm unsure about the most efficient way to do this.
I was thinking that I could possibly have a dictionary of numbers and look for matches in the string.
Or I could trim away anything that came before the word "third" and after the word "ninth" and process the results.
string
"What is the third, fifth, sixth and ninth characters to question A"
desired output
array(3,5,6,9);
Rather ugly code (because of "global"), but simply working
$dict = array('third' => 3, 'fifth' => 5, 'sixth' => 6, 'ninth' => 9);
$string = 'What is the third, fifth, sixth and ninth characters to question A';
$output = null;
if (preg_match_all('/(' . implode('|', array_keys($dict)) . ')/', $string, $output))
$output = array_map(function ($in) { global $dict; return $dict[$in]; }, $output[1]);
print_r($output);
Update
The exact code without use of "global":
$dict = array('third' => 3, 'fifth' => 5, 'sixth' => 6, 'ninth' => 9);
$string = 'What is the third, fifth, sixth and ninth characters to question A';
$output = null;
if (preg_match_all('/(' . implode('|', array_keys($dict)) . ')/', $string, $output))
$output = array_map(function ($in) use ($dict) { return $dict[$in]; }, $output[1]);
print_r($output);
See this, complete work for you!
<?php
function get_numbers($s) {
$str2num = array(
'first' => 1,
'second' => 2,
'third' => 3,
'fourth' => 4,
'fifth' => 5,
'sixth' => 6,
'seventh' => 7,
'eighth' => 8,
'ninth' => 9,
);
$pattern = "/(".implode(array_keys($str2num), '|').")/";
preg_match_all($pattern, $s, $matches);
$ans = array();
foreach($matches[1] as $key) {
array_push($ans, $str2num[$key]);
}
return $ans;
}
var_dump(get_numbers("What is the third, fifth, sixth and ninth characters to question A"));
$string = "What is the first, third, first, first, third, sixth and ninth characters to question A";
$numbers = array('first' => 1, 'second' => 2, 'third' => 3); //...
preg_match_all("(".implode('|',array_keys($numbers)).")", $string, $matches );
$result = array();
foreach($matches[0] as $match){
$result[] = $numbers[$match];
}
var_dump($result);
Related
I Have an Array like this,
$arr = array_diff($cart_value_arr,$cart_remove_arr);
I Want to convert it to string without using implode method anyother way is there? And Also i want to remove $cart_remove_arr from $cart_value_arr the array_diff method i used it is correct?
You can use json_encode
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
This will also work on multi dimensional arrays
Will result to:
{"a":1,"b":2,"c":3,"d":4,"e":5}
Doc: http://php.net/manual/en/function.json-encode.php
Another way is the classic foreach plus string concatenation
$string = '';
foreach ($arr as $value) {
$string .= $value . ', ';
}
echo rtrim($string, ', ');
Yet another way is to use serialize() (http://php.net/manual/en/function.serialize.php), as simple as...
$string = serialize($arr);
This can handle most types and unserialize() to rebuild the original value.
$cart_remove_arr = array(0 => 1, 1=> 2, 2 => 3);
$cart_value_arr = array(0 => 5, 1=> 2, 2 => 3, 3 => 4, 4 => 6);
$arr = array_diff($cart_value_arr, $cart_remove_arr);
echo '<pre>';
print_r($arr);
$string = "";
foreach($arr as $value) {
$string .= $value.', ';
}
echo $string;
**Output: Naveen want to remove $cart_remove_arr from $cart_value_arr
Remaining array**
Array
(
[0] => 5
[3] => 4
[4] => 6
)
he want a similar out as implode()
**String** 5, 4, 6,
I am trying to chunk my sku into smaller portions, unfortunetly the below code does not work as
sometimes my sku's are 12 digits, sometimes 10.
$this->skuMap['simple'][$sku] = [
'RefId' => substr($sku, 0, 5),
'Color' => substr($sku, 5, -3),
'Name' => $product->getName(),
];
I'm pretty sure there is a way to preg_split this, but I'm not certain of the regex, here was my failed attempt.
$sku = preg_split(['/^[0-9]{5}/','/([0-9]{5})([0-9]{3})/'], $sku, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
The regex you're looking for is "/^([0-9]{5})([0-9]{3})([0-9]+)$/".
$matches = [];
if (preg_match("/^([0-9]{5})([0-9]{3})([0-9]+)$/", $string, $matches) !== -1) {
$id = $matches[1];
$color = $matches[2];
$info = $matches[3];
} else {
throw new \RuntimeException("bad SKU");
}
Broken down it's five digits, 3 digits, then any number of digits, each in separate groups.
Accepting above, but this also works.
$this->skuMap['simple'][$sku] = [
'RefId' => substr($sku,0,5),
'Color' => substr(substr_replace($sku,'',0,5),0,3),
'Name' => $product->getName(),
];
Given:
An array of model numbers i.e (30, 50, 55, 85, 120)
a single string that contains model number that is guaranteed to be in the array, immediately followed by a submodel number. Submodel can be a number between 1 and 50.
Examples: 12022, 502, 55123
Wanted:
a single output string containing just the submodel number, i.e 22, 2, 123
aka the front part of string that was in array is removed
Examples: 12022 => 22, 1202 => 2, 502 => 2, 55123 => 123, 5050 => 50
I can think of various ways to do this, but looking for something concise. Bonus if it's also aesthetically beautiful :)
<?php
$arr = array(30, 50, 55, 85, 120); // Array of forbiddens
$str = "12022, 502, 55123"; // Your string
$sep = array_map('trim', explode(",", $str));
foreach($sep as $key => $value)
foreach ($arr as $sec)
if(preg_match("#^$sec#", $value))
$sep[$key] = substr($value, strlen($sec));
print_r($sep);
Output:
Array
(
[0] => 22
[1] => 2
[2] => 123
)
My attempt:
$v = array(120, 50, 55);
print removeModel("502", $v);
function removeModel($str, $v)
{
foreach($v as $value)
if (preg_match("/^$value/",$str))
return preg_replace("/$value/", "", $str);
}
You could use substr($yourString, $x) function to cut first $x characters from $yourString.
My idea:
<?php
$str = "502"; //or "12022" for testing
if(strlen($str)==3)
$newStr=substr($str, (strlen($str)-1)); //502 -> 2
else
$newStr=substr($str, (strlen($str)-2)); //12022 -> 22
echo ltrim($newStr, '0');
?>
just loop the array and replace in the string every array value to empty string
Let's say I have these two related arrays:
$letters = ['a', 'b', 'c', 'd', 'e'];
$replace = [1, 5, 10, 15, 20];
And a string of letters separated by spaces.
$text = "abd cde dee ae d";
I want to convert consecutive letters to their respective numbers, sum the numbers, then replace the original letters with the total.
Using str_replace() isn't right because the values are compressed as a string before I can sum them.
$re = str_replace($letters, $replace, $text);
echo $re; //this output:
1515 101520 152020 120 15
I actually want to sum the above numbers for each "word" and the result should be:
21 45 55 21 15
What I tried:
$resultArray = explode(" ", $re);
echo array_sum($resultArray).'<br />';
It incorrectly outputs:
255190
EDIT:
My actual data contains arabic multibyte characters.
$letters = array('ا', 'ب','ج','د' ) ;
$replace = array(1, 5, 10, 15 ) ;
$text = "جا باب جب";
Convert the string into an array and use array_sum.
array_sum(explode(' ', $re));
Edit
Sorry, misunderstood:
$letters = array('a','b','c', 'd', 'e');
$replace = array( 1, 5, 10, 15 , 20);
$text = "abd cde dee ae d" ;
$new_array = explode(' ', $text);
$sum_array = array();
foreach ($new_array as $string)
{
$nums = str_split($string);
foreach ($nums as &$num)
{
$num = str_replace($letters, $replace, $num);
}
$sum_array[] = array_sum($nums);
}
echo implode(' ', $sum_array);
Instead of replacing the letters with numbers I would suggest just looking up the letters in the replace array one at a time:
EDIT
<?php
$text = "abd cde dee ae d";
$replace = array('a' => 1, 'b' => 5, 'c' => 10, 'd' => 15, 'e' => 20);
$letters = str_split($text);
$sums = array(0);
foreach ($letters as $letter) {
// Add a new element to the sum array.
if ($letter == ' ') {
$sums[] = 0;
} else {
$sums[count($sums) - 1] += $replace[$letter];
}
}
echo implode(" ", $sums);
?>
Here is a working example:
http://codepad.org/Cw71zuKD
Because the summed results after translating sequences of letters is meant to be used as the replacement text in the output string, I find preg_replace_callback() to be a fitting tool to encapsulate and deliver the required logic.
Isolate a substring of letters
Split each respective set of letters into an array of individual characters
Perform the necessary translation to integer values
Sum the array of numbers
Replace the original substring with the summed value
Repeat until all substrings are replaced
Code: (Demo)
$letters = ['a','b','c', 'd', 'e'];
$replace = [1, 5, 10, 15 , 20];
$text = "abd cde dee ae d";
echo preg_replace_callback(
'/[a-e]+/',
fn($m) => array_sum(
str_replace(
$letters,
$replace,
str_split($m[0])
)
),
$text
);
Output:
21 45 55 21 15
For multibyte processing: (Demo)
$letters = array('ا', 'ب','ج','د' ) ;
$replace = array(1, 5, 10, 15 ) ;
$text = "جا باب جب";
echo preg_replace_callback(
'/\S+/u',
fn($m) => array_sum(
str_replace(
$letters,
$replace,
mb_str_split($m[0])
)
),
$text
);
Output;
11 11 15
i have this string -
$result = "ABCDE";
and i want to seperate them to 3 parts
(like part 1 = A, part 2 = B, part 3 = C..., part 5 = E)
,give a name to each of them
part 1(A) = Apple
part 2(B) = Orange
part 3(C) = Ice-cream
part 3(D) = Water
part 5(E) = Cow
then the finally output is like
Output : You choose Apple, Orange, Ice-cream, Water, Cow
or like this
$result = "ACE";
Output : You choose Apple, Ice-cream, Cow
i have tried using array
$result = "ABCDE";
$showing = array(A => 'Apple , ', B => 'Orange , ', C => 'Ice-cream , ',
D => 'Water , ', E => 'Cow , ');
echo $showing[$result];
but i got nothing while output, seems array is not working in fixed string.
i want to know how to do it
For one line magic:
echo implode('',array_intersect_key($showing,array_flip(str_split($result))));
You can use the function str_split to split the string into individual letters, which can later be used as keys of your associative array.
Also you don't need to add comma at the end of each string. Instead you can use the implode function to join your values:
$input = "ABCDE";
$showing = array('A' => 'Apple', 'B' => 'Orange', 'C' => 'Ice-cream',
'D' => 'Water', 'E' => 'Cow');
$key_arr = str_split($input);
$val_arr = array();
foreach($key_arr as $key) {
$val_arr[] = $showing[$key];
}
echo "You choose ".implode(',',$val_arr)."\n";
You can access characters from a string similar to elements in an array, like this:
$string = "ABCDE";
echo $string[2]; // "C"
Technically, it's not really treating it like an array, it just uses a similar syntax.
You could use
$choices= array('A' => 'Apple', 'B' => 'Orange', 'C' => 'Ice-cream',
'D' => 'Water', 'E' => 'Cow');
$selected[] = array();
for ($i = 0, $len = strlen($result); $i < $len; $i++) {
$selected[] = $choices[$string[$i]];
}
echo "You have selected: " . implode(', ', $selected);
Although str_split, as others have suggested, would also work.