Count occurrence of words and only 1 in the same phrases - php

I have a problem where I need to count the number of times a word occurs in a given array.
I want the code to increase the count of a word ('instagrammm') by 1 if the word is in the same phrases.
Here is my code:
$output = array();
$buzzes = ['instagramm some text instagramm', 'instagramm some text' , 'instagramm some text' , 'instagramm some text'];
foreach ($buzzes as $buzz) {
$flag = 0;
$words = explode(" ",$buzz);
foreach ($words as $word)
{
$word = mb_convert_case($word, MB_CASE_LOWER, "UTF-8");
$word = preg_replace('/^[^A-Za-z0-9\-]|[^A-Za-z0-9\-]$/', '', $word);
if(strlen($word) > 2){
if (array_key_exists($word, $output)){
$output[$word]++;
}else{
$output[$word] = 1;
}
}
}
}
Here is the expected result:
Array
(
[instagramm] => 4
[some] => 4
[text] => 4
)

Try this one. It will be faster with fewer comparisons and allocations:
foreach ($buzzes as $buzz) {
$words = array_unique(explode(' ',$buzz));
foreach ($words as $word) {
$word = mb_convert_case($word, MB_CASE_LOWER, "UTF-8");
$word = preg_replace('/^[^A-Za-z0-9\-]|[^A-Za-z0-9\-]$/', '', $word);
if(strlen($word) > 2){
if (array_key_exists($word, $output)){
$output[$word]++;
}else{
$output[$word] = 1;
}
}
}
}
take a look:
// My version
Took: 0.178099
Array
(
[instagramm] => 4
[some] => 4
[text] => 4
)
// accepted version
Took: 25.308847
Array
(
[instagramm] => 4
[some] => 4
[text] => 4
)

seems you are suppose to have another condition in your piece of code.
just modified your code with a condition.
$output = array();
$buzzes = array('instagramm some text instagramm', 'instagramm some text' , 'instagramm some text' , 'instagramm some text');
foreach ($buzzes as $buzz) {
$flag = 0;
$words = explode(" ",$buzz);
$wordArr = array();
foreach ($words as $word)
{
$word = mb_convert_case($word, MB_CASE_LOWER, "UTF-8");
$word = preg_replace('/^[^A-Za-z0-9\-]|[^A-Za-z0-9\-]$/', '', $word);
if(!in_array(strtolower($word),$wordArr)) {
if(strlen($word) > 2){
if (array_key_exists($word, $output)){
$output[$word]++;
}else{
$output[$word] = 1;
}
}
$wordArr[] = strtolower($word);
}
}
}
print_r($output);

Here's a simplified version of the code:
$output = array();
$buzzes = ['instagramm some text instagramm', 'instagramm some text' , 'instagramm some text' , 'instagramm some text'];
foreach( explode( ' ', implode( ' ', $buzzes ) ) as $word )
{
$word = strtolower( trim( $word ) );
if( !empty( $word ) )
{
if( isset( $output[ $word ] ) )
{
$output[ $word ]++;
}
else{ $output[ $word ] = 1; }
}
}
Output:
Array
(
[instagramm] => 5
[some] => 4
[text] => 4
)

Related

PHP Regular Expression preg_match from Array with Multine doesn't match all block

Wondering if anyone out there can help me with the following regular expression, i can't match the block multine CF.{Coordonnees Abonne}: when used in PHP's preg_match function.
What is weird is when I do regex online it seems to work despite the block is in another group regex101 example
Here is the code : source code
<?php
$response = array(
1 => 'CF.{Temps}: 1',
2 => 'CF.{Etat}: return',
3 => 'CF.{Code}: 2',
4 => 'CF.{Values}: plaque',
5 => '',
6 => 'CF.{Coordonnees}: LA PERSONNE',
7 => ' ',
8 => ' 10000 LA VILLE',
9 => ' ',
10 => ' 0500235689',
11 => ' 0645788923',
12 => ' Login : test#mail.com',
13 => ' Password : PassWord!',
14 => '',
15 => 'CF.{Groupe}: 3',
16 => 'CF.{Date}: 4',
);
print_r(parseResponseBody($response));
function parseResponseBody(array $response, $delimiter = ':')
{
$responseArray = array();
$lastkey = null;
foreach ($response as $line) {
if(preg_match('/^([a-zA-Z0-9]+|CF\.{[^}]+})' . $delimiter . '\s(.*)|([a-zA-Z0-9].*)$/', $line, $matches)) {
$lastkey = $matches[1];
$responseArray[$lastkey] = $matches[2];
}
}
return $responseArray;
}
?>
Output :
Array
(
[CF.{Temps}] => 1
[CF.{Etat}] => return
[CF.{Code}] => 2
[CF.{Values}] => plaque
[CF.{Coordonnees}] => LA PERSONNE
[] =>
[CF.{Groupe}] => 3
[CF.{Date}] => 4
)
And there is the wanted final result that i need to extract :
Array
(
[CF.{Temps}] => 1
[CF.{Etat}] => return
[CF.{Code}] => 2
[CF.{Values}] => plaque
[CF.{Coordonnees}] => LA PERSONNE
10000 LA VILLE
0500235689
0645788923
Login : test#mail.com
Password : PassWord!
[CF.{Groupe}] => 3
[CF.{Date}] => 4
)
You have to check if current value at iteration starts with a block or not. Not both at same time though:
function parseResponseBody(array $response, $delimiter = ':') {
$array = [];
$lastIndex = null;
foreach ($response as $line) {
if (preg_match('~^\s*(CF\.{[^}]*})' . $delimiter . '\s+(.*)~', $line, $matches))
$array[$lastIndex = $matches[1]] = $matches[2];
elseif ((bool) $line)
$array[$lastIndex] .= PHP_EOL . $line;
}
return $array;
}
Live demo
I would do that this way:
function parse($response, $del=':', $nl="\n") {
$pattern = sprintf('~(CF\.{[^}]+})%s \K.*~A', preg_quote($del, '~'));
foreach ($response as $line) {
if ( preg_match($pattern, $line, $m) ) {
if ( !empty($key) )
$result[$key] = rtrim($result[$key]);
$key = $m[1];
$result[$key] = $m[0];
} else {
$result[$key] .= $nl . $line;
}
}
return $result;
}
var_export(parse($response));
demo
The key is stored in the capture group 1 $m[1] but the whole match $m[0] returns only the value part (the \K feature discards all matched characters on its left from the match result). When the pattern fails, the current line is appended for the last key.
The regex is fine, you just need to handle the case when there is no key:
function parseResponseBody(array $response, $delimiter = ':')
{
$responseArray = array();
$key = null;
foreach ($response as $line) {
if(preg_match('/^([a-zA-Z0-9]+|CF\.{[^}]+})' . $delimiter . '\s(.*)|([a-zA-Z0-9].*)$/', $line, $matches)) {
$key = $matches[1];
if(empty($key)){
$key = $lastKey;
$responseArray[$key] .= PHP_EOL . $matches[3];
}else{
$responseArray[$key] = $matches[2];
}
$lastKey = $key;
}
}
return $responseArray;
}
https://3v4l.org/rFIbk

PHP get array of search terms from string

Is there an easy way to parse a string for search terms including negative terms?
'this -that "the other thing" -"but not this" "-positive"'
would change to
array(
"positive" => array(
"this",
"the other thing",
"-positive"
),
"negative" => array(
"that",
"but not this"
)
)
so those terms could be used to search.
The code below will parse your query string and split it up into positive and negative search terms.
// parse the query string
$query = 'this -that "-that" "the other thing" -"but not this" ';
preg_match_all('/-*"[^"]+"|\S+/', $query, $matches);
// sort the terms
$terms = array(
'positive' => array(),
'negative' => array(),
);
foreach ($matches[0] as $match) {
if ('-' == $match[0]) {
$terms['negative'][] = trim(ltrim($match, '-'), '"');
} else {
$terms['positive'][] = trim($match, '"');
}
}
print_r($terms);
Output
Array
(
[positive] => Array
(
[0] => this
[1] => -that
[2] => the other thing
)
[negative] => Array
(
[0] => that
[1] => but not this
)
)
For those looking for the same thing I have created a gist for PHP and JavaScript
https://gist.github.com/UziTech/8877a79ebffe8b3de9a2
function getSearchTerms($search) {
$matches = null;
preg_match_all("/-?\"[^\"]+\"|-?'[^']+'|\S+/", $search, $matches);
// sort the terms
$terms = [
"positive" => [],
"negative" => []
];
foreach ($matches[0] as $i => $match) {
$negative = ("-" === $match[0]);
if ($negative) {
$match = substr($match, 1);
}
if (($match[0] === '"' && substr($match, -1) === '"') || ($match[0] === "'" && substr($match, -1) === "'")) {
$match = substr($match, 1, strlen($match) - 2);
}
if ($negative) {
$terms["negative"][] = $match;
} else {
$terms["positive"][] = $match;
}
}
return $terms;
}

Imploding with "and" in the end?

I have an array like:
Array
(
[0] => Array
(
[kanal] => TV3+
[image] => 3Plus-Logo-v2.png
)
[1] => Array
(
[kanal] => 6\'eren
[image] => 6-eren.png
)
[2] => Array
(
[kanal] => 5\'eren
[image] => 5-eren.png
)
)
It may expand to several more subarrays.
How can I make a list like: TV3+, 6'eren and 5'eren?
As array could potentially be to further depths, you would be best off using a recursive function such as array_walk_recursive().
$result = array();
array_walk_recursive($inputArray, function($item, $key) use (&$result) {
array_push($result, $item['kanal']);
}
To then convert to a comma separated string with 'and' separating the last two items
$lastItem = array_pop($result);
$string = implode(',', $result);
$string .= ' and ' . $lastItem;
Took some time but here we go,
$arr = array(array("kanal" => "TV3+"),array("kanal" => "5\'eren"),array("kanal" => "6\'eren"));
$arr = array_map(function($el){ return $el['kanal']; }, $arr);
$last = array_pop($arr);
echo $str = implode(', ',$arr) . " and ".$last;
DEMO.
Here you go ,
$myarray = array(
array(
'kanal' => 'TV3+',
'image' => '3Plus-Logo-v2.png'
),
array(
'kanal' => '6\'eren',
'image' => '6-eren.png'
),
array(
'kanal' => '5\'eren',
'image' => '5-eren.png'
),
);
foreach($myarray as $array){
$result_array[] = $array['kanal'];
}
$implode = implode(',',$result_array);
$keyword = preg_replace('/,([^,]*)$/', ' & \1', $implode);
echo $keyword;
if you simply pass in the given array to implode() function,you can't get even the value of the subarray.
see this example
assuming your array name $arr,codes are below
$length = sizeof ( $arr );
$out = '';
for($i = 0; $i < $length - 1; $i ++) {
$out .= $arr [$i] ['kanal'] . ', ';
}
$out .= ' and ' . $arr [$length - 1] ['kanal'];
I think it would work to you:
$data = array(
0 =>['kanal' => 'TV1+'],
1 =>['kanal' => 'TV2+'],
2 =>['kanal' => 'TV3+'],
);
$output = '';
$size = sizeof($data)-1;
for($i=0; $i<=$size; $i++) {
$output .= ($size == $i && $i>=2) ? ' and ' : '';
$output .= $data[$i]['kanal'];
$output .= ($i<$size-1) ? ', ' : '';
}
echo $output;
//if one chanel:
// TV1
//if two chanel:
// TV1 and TV2
//if three chanel:
// TV1, TV2 and TV3
//if mote than three chanel:
// TV1, TV2, TV3, ... TV(N-1) and TV(N)
$last = array_slice($array, -1);
$first = join(', ', array_slice($array, 0, -1));
$both = array_filter(array_merge(array($first), $last));
echo join(' and ', $both);
Code is "stolen" from here: Implode array with ", " and add "and " before last item
<?php
foreach($array as $arr)
{
echo ", ".$arr['kanal'];
}
?>

Parse Unserialized array

i have a unserialized array
like this
Array (
[status] => 1
[msg] => Transaction Fetched Successfully
[transaction_details] => Array (
[100002982] => Array (
[mihpayid] => 4149968
[request_id] => 635788
[bank_ref_num] => NINETE.31845.28052012
[amt] => 3295.00
[disc] => 0.00
[mode] => CC
[retries] => 0
[status] => success
[unmappedstatus] => captured
)
)
)
i want to parse this array
so that i can get the value to status ie Success
how i can do that
$success = $array['transaction_details']['100002982']['status'];
$arr['transaction_details']['100002982']['status']
The PHP documentation has a user comment which suggests a method to parse the output of print_r (similar to the above). It can be found here: http://www.php.net/manual/en/function.print-r.php#93529
Here is a copy of the source code found at the above link:
<?php
function print_r_reverse($in) {
$lines = explode("\n", trim($in));
if (trim($lines[0]) != 'Array') {
// bottomed out to something that isn't an array
return $in;
} else {
// this is an array, lets parse it
if (preg_match("/(\s{5,})\(/", $lines[1], $match)) {
// this is a tested array/recursive call to this function
// take a set of spaces off the beginning
$spaces = $match[1];
$spaces_length = strlen($spaces);
$lines_total = count($lines);
for ($i = 0; $i < $lines_total; $i++) {
if (substr($lines[$i], 0, $spaces_length) == $spaces) {
$lines[$i] = substr($lines[$i], $spaces_length);
}
}
}
array_shift($lines); // Array
array_shift($lines); // (
array_pop($lines); // )
$in = implode("\n", $lines);
// make sure we only match stuff with 4 preceding spaces (stuff for this array and not a nested one)
preg_match_all("/^\s{4}\[(.+?)\] \=\> /m", $in, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
$pos = array();
$previous_key = '';
$in_length = strlen($in);
// store the following in $pos:
// array with key = key of the parsed array's item
// value = array(start position in $in, $end position in $in)
foreach ($matches as $match) {
$key = $match[1][0];
$start = $match[0][1] + strlen($match[0][0]);
$pos[$key] = array($start, $in_length);
if ($previous_key != '') $pos[$previous_key][1] = $match[0][1] - 1;
$previous_key = $key;
}
$ret = array();
foreach ($pos as $key => $where) {
// recursively see if the parsed out value is an array too
$ret[$key] = print_r_reverse(substr($in, $where[0], $where[1] - $where[0]));
}
return $ret;
}
}
?>
I have not tested the above function.

create associative array from array

How can I transform
Array1
(
[0] => Some Text
[1] => Some Other Text (+£14.20)
[2] => Text Text (+£26.88)
[3] => Another One (+£68.04)
)
Into associative array like the one below:
Array2
(
[Some Text] => 0 //0 since there is no (+£val) part
[Some Other Text] => 14.20
[Text Text] => Text Text 26.88
[Another One] => 68.04
)
$newArray = array();
foreach( $oldArray as $str ) {
if( preg_match( '/^(.+)\s\(\+£([\d\.]+)\)$/', $str, $matches ) ) {
$newArray[ $matches[1] ] = (double)$matches[2];
} else {
$newArray[ $str ] = 0;
}
}
Something like this should work:
$a2 = array();
foreach ($Array1 as $a1) {
if (strpos($a1, '(') > 0) {
$text = substr($a1, 0, strpos($a1, '('));
$value = substr($a1, strpos($a1, '(')+3, strpos($a1, ')')-1);
} else {
$text = $a1;
$value = 0;
}
$a2[$text] = $value;
}
print_r($a2);
EDIT:
You can do this using explode method as well:
$a2 = array();
foreach ($Array1 as $a1) {
$a1explode = explode("(", $a1, 2);
$text = $a1explode[0];
if ($a1explode[1]) {
$value = substr($a1explode[1],3);
} else {
$value = 0;
}
$a2[$text] = $value;
}
print_r($a2);

Categories