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(),
];
Related
As you can see I have the thousands_sep with a dot, and "Summe" as the last column obv. is trying to calculate the sum of the rows but it uses 1556€ as 1.556€ thats why i get 234€ instead of 1.788
for ( $a = 0; $a < $i; $a++){
$sum += $tabledata[$a]['value'];
}
$ajaxreturn['beschriftungen'] = $beschriftungen;
$ajaxreturn['chartData'] = $chartdata;
$ajaxreturn['tablehead'] = $tablehead;
$tabledata[(count($tabledata))]= array('category'=>"Summe",'value' => number_format($sum, 0, ',', '.').'€', 'id' => $i);
I tried to change many things but what i need is that the input is "converted" to a number without the '.'
$chartdata[] = array('date' => $iddate, 'value' => round($zeile['summe']), 'id' => $i);
$tabledata[] = array('category' => $beschriftung, 'value' => number_format($zeile['summe'], 0, '', '.').'€', 'id' => $i);
Instead of trying to calculate the sum from the formatted number array ($tabledata), you should calculate the sum alongside the tabledata, like:
$beschriftungen[$iddate] = $beschriftung;
$chartdata[] = array('date' => $iddate, 'value' => round($zeile['summe']), 'id' => $i);
$tabledata[] = array('category' => $beschriftung, 'value' => number_format($zeile['summe'], 0, '', '.').'€', 'id' => $i);
$sum += $zeile['summe'];
Use str_replace('.', '', $value); or even better, preg_replace('/\D/', '', $value). preg_replace will remove also the currency symbol and possible spaces.
I have a PHP array:
$excerpts = array(
'I love cheap red apples',
'Cheap red apples are what I love',
'Do you sell cheap red apples?',
'I want red apples',
'Give me my red apples',
'OK now where are my apples?'
);
I would like to find all the n-grams in these lines to get a result like this:
cheap red apples: 3
red apples: 5
apples: 6
I tried to implode the array and then parse it, but it's stupid because new n-grams can be found because of the concatenation of strings that have nothing to see between each other.
How would you proceed?
I want to find group of words without knowing them before although
with your function I need to provide them before anything
Try this:
mb_internal_encoding('UTF-8');
$joinedExcerpts = implode(".\n", $excerpts);
$sentences = preg_split('/[^\s|\pL]/umi', $joinedExcerpts, -1, PREG_SPLIT_NO_EMPTY);
$wordsSequencesCount = array();
foreach($sentences as $sentence) {
$words = array_map('mb_strtolower',
preg_split('/[^\pL+]/umi', $sentence, -1, PREG_SPLIT_NO_EMPTY));
foreach($words as $index => $word) {
$wordsSequence = '';
foreach(array_slice($words, $index) as $nextWord) {
$wordsSequence .= $wordsSequence ? (' ' . $nextWord) : $nextWord;
if( !isset($wordsSequencesCount[$wordsSequence]) ) {
$wordsSequencesCount[$wordsSequence] = 0;
}
++$wordsSequencesCount[$wordsSequence];
}
}
}
$ngramsCount = array_filter($wordsSequencesCount,
function($count) { return $count > 1; });
I'm assuming you only want repeated group of words.
The ouput of var_dump($ngramsCount); is:
array (size=11)
'i' => int 3
'i love' => int 2
'love' => int 2
'cheap' => int 3
'cheap red' => int 3
'cheap red apples' => int 3
'red' => int 5
'red apples' => int 5
'apples' => int 6
'are' => int 2
'my' => int 2
The code could be optimized to, for instance, use less memory.
The code provided by Pedro Amaral Couto above is very good.
Since I use it for French, I modified the regular expression as follows:
$sentences = preg_split('/[^\s|\pL-\'’]/umi', $joinedExcerpts, -1, PREG_SPLIT_NO_EMPTY);
This way, we can analyze the words containing hyphens and apostrophes ("est-ce que", "j'ai", etc.)
Try this (using the implode, since that's you've mentioned as an attempt):
$ngrams = array(
'cheap red apples',
'red apples',
'apples',
);
$joinedExcerpts = implode("\n", $excerpts);
$nGramsCount = array_fill_keys($ngrams, 0);
var_dump($ngrams, $joinedExcerpts);
foreach($ngrams as $ngram) {
$regex = '/(?:^|[^\pL])(' . preg_quote($ngram, '/') . ')(?:$|[^\pL])/umi';
$nGramsCount[$ngram] = preg_match_all($regex, $joinedExcerpts);
}
Assuming you just want to count the number of occurrences of a string:
$cheapRedAppleCount = 0;
$redAppleCount = 0;
$appleCount = 0;
for($i = 0; $i < count($excerpts); $i++)
{
$cheapRedAppleCount += preg_match_all('cheap red apples', $excerpts[$i]);
$redAppleCount += preg_match_all('red apples', $excerpts[$i]);
$appleCount += preg_match_all('apples', $excerpts[$i]);
}
preg_match_all returns the number of matches in a given string so you can just add the number of matches onto a counter.
preg_match_all for more information.
Apologies if I misunderstood.
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
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);
I have a string which contains a math formula, like T + ST + s + t ...
I'm replacing all those letter identifiers with numbers using:
$ids = array(
'T' => $t1,
'ST', => $st,
's', => $s1,
't', => $t2,
'N', => 1,
);
foreach ($ids as $id => $value) {
if (strpos($formula, $id) !== false) {
$formula = str_replace($id, $value, $formula);
}
}
Which is ok in certain situations.
But if the formula has ST at the beginning I get a string like S345324 ..
I fixed this by moving ST in the first position in my array, but I feel it's not really the best option :)
Are there any other "nicer" solutions?
Are you looking for strtr()?
$ids = array(
'T' => $t1,
'ST' => $st,
's' => $s1,
't' => $t2,
'N' => 1,
);
$formula = strtr($formula, $ids);
Note that since strtr() always tries to find the longest possible match, it won't replace occurrences of ST with S$t1 (instead of $st), regardless of how your $replace_pairs array is ordered.
Example (as seen on codepad):
$ids = array(
'T' => 10,
'ST' => 20,
's' => 30,
't' => 40,
'N' => 1,
);
$formula = 'T + ST + s + t';
echo strtr($formula, $ids);
Prints:
10 + 20 + 30 + 40