PHP get words with length longer than 3 from string - php

Is there a function that can cut words from a string that are small length e.g. "the, and, you, me, or" all these short words that are common in all sentences. i want to use this function to fill a fulltext search with criteria
before the method:
$fulltext = "there is ongoing work on creating a formal PHP specification.";
outcome:
$fulltext_method_solution = "there ongoing work creating formal specification."

$fulltext = "there is ongoing work on creating a formal PHP specification.";
$words = array_filter(explode(' ', $fulltext), function($val){
return strlen($val) > 3; // filter words having length > 3 in array
});
$fulltext_method_solution = implode(' ', $words); // join words into sentence

try this:
$fulltext = "there is ongoing work on creating a formal PHP specification.";
$result=array();
$array=explode(" ",$fulltext);
foreach($array as $key=>$val){
if(strlen($val) >3)
$result[]=$val;
}
$res=implode(" ",$result);

You can simply use implode, explode along with array_filter
echo implode(' ',array_filter(explode(' ',$fulltext),function($v){ return strlen($v) > 3;}));
or simply use preg_replace as
echo preg_replace('/\b[a-z]{1,3}\b/i','',$fulltext);

try this:
$stringArray = explode(" ", $fulltext);
foreach ($stringArray as $value)
{
if(strlen($value) < 3)
$fulltext= str_replace(" ".$value." " ," ",$fulltext);
}
Here is a working DEMO

Simply explode the string and check for the strlen()
$fulltext = "there is ongoing work on creating a formal PHP specification.";
$ex = explode(' ',$fulltext);
$res = '';
foreach ($ex as $txt) {
if (strlen($txt) > 3) {
$res .= $txt . ' ';
}
}
echo $res;

By using preg_replace
echo $string = preg_replace(array('/\b\w{1,3}\b/','/\s+/'),array('',' '),$fulltext);

This will also produce the desired results:
<?php
$fulltext = "there is ongoing work on creating a formal PHP specification.";
$fulltext = preg_replace('/(\b.{1,3}\s)/',' ',$fulltext);
echo $fulltext;
?>

Related

Highlighting strings with different orders in PHP

I am trying to highlight the strings. Whether they are in the sequence or not.
Like this -
$str = "star 5 hotel";
$keywords = "5 star hotels";
There is my function. It only highlights the last matching string.Here $str contains the search string. $keyword contains that string which i have stored into database
How can i highlight each matching string.
function highlight($str, $keyword) {
$str = "star hotel 5";
$keyword = "5 star hotel";
foreach($look as $find){
if(strpos($keyword, $find) !== false) {
if(!isset($highlight)){
$highlight[] = $find;
} else {
if(!in_array($find,$highlight)){
$highlight[] = $find;
}
}
}
}
if(isset($highlight)){
foreach($highlight as $replace){
$str = str_ireplace($replace,'<b>'.$replace.'</b>',$keyword);
$stra[] = str_ireplace($replace,'<b>'.$replace.'</b>',$keyword);
echo "<pre>";
print_r ($stra);
echo "</pre>";
}
}
echo $str."<br>";
die();
return $str;
}
But when i put this into an array and when i print this array $stra[]. It given me this
Array
(
[0] => 5 star hotel
[1] => 5 star hotel
[2] => 5 star hotel
)
I can not find way to combine these.
Output : -If have that keyword which is searching . then this must be Highlighted..
5 star hotel
This is what I assumed:-
I assume that you want to search each word of the search sting in the given string and if and only if all the words found then make string in bold (complete string).
Then do like below (Explanation given in comments):-
<?php
$search = "star 5 hotel"; //search string
$string = "5 star hotels"; // string in which you want to search
function highlight($search, $string) {
$new_search = array_unique(array_filter(explode(" " ,$search)));//explode search string
$found_count = 0; //create a counter
foreach($new_search as $find){ // iterate over search words array
if(strpos($string, $find) !== false) { // if word found in the string
$found_count +=1; // increase the counter
}
}
if(count($new_search) == $found_count){ //check that all words found in the string
$string = "<b>". $string ."</b>"; // if yes then make each word of the string bold
}
return $string; //return the newly modified string
}
echo highlight($search, $string); // echo newly modified string
Output:- https://eval.in/838325
You can use an array, and strtr() function. :)
$str = "the quick brown fox";
$keywords = "quick fox brown";
$matches = explode(" ",$keywords);
foreach ($matches as $v) {
$arr_matches[$v] = "<b>".$v."</b>";
}
$str = strtr($str, $arr_matches);
I know it's late but here is one way to make a double loop that will keep the bloat tags to a minimum and handle extra words in the sentence (in what I think is correct way).
It checks if the word is in match list, if yes loop til there is a not matching word.
Add the tags around those two words and go back to main loop.
$str = "star 5 hotel";
$strarr =explode(" ", $str);
$keywords = "a 5 star uinique hotel";
$arr = explode(" ", $keywords);
For($i=0; $i < count($arr) ; $i++){
If(in_array($arr[$i], $strarr)){
$j=$i;
While(in_array($arr[$j], $strarr) && $j < count($arr)){
$j++;
}
$j--;
$arr[$i] = "<b>" . $arr[$i];
$arr[$j] = $arr[$j] . "</b>";
$i=$j;
}
}
Echo implode(" ", $arr);
Output of above example:
a <b>5 star</b> uinique <b>hotel</b>
https://3v4l.org/pKE4X
You can use an array to achieve:
$str = 'This is some 5 start hotel in US';
$keyWords = ['5', 'star', 'hotel'];
$strToCheck = explode(' ', $str);
foreach ($keyWords as $k => $v)
{
if (in_array($v, $strToCheck)) {
//do something
}
}
this creates the string as an array, this means we can use in_array to check, then inside the if statement do whatever :)
references:
http://php.net/manual/en/function.in-array.php
http://php.net/manual/en/function.explode.php
Why don't you just iterate over your keywords and replace them:
$str = "This is a star 5 hotel located in New York";
$keywords = array("5","star","hotels");
foreach (array_expression as $key => $value){
$str = str_replace($value, "<b>".$value."</b>", $str);
}
Simple and failsafe if you don't have double keywords.
Or if your keywords need to be a something-separated string:
$str = "This is a star 5 hotel located in New York";
$keywords = "5 star hotel";
$arraykeywords = explode(" ",$keywords);
foreach (array_expression as $key => $value){
$str = str_replace($value, "<b>".$value."</b>", $str);
}
To filter double keywords use array_unique:
$str = "This is a star 5 hotel located in New York";
$keywords = "5 star hotel star";
$arraykeywords = array_unique(explode(" ",$keywords));
foreach (array_expression as $key => $value){
$str = str_replace($value, "<b>".$value."</b>", $str);
}
After a lot of discussion about regex (see the comments), this is the approach using #Andreas's regex:
$str = "This is a star 5 hotel located in New York";
$keywords = "5 star hotel star";
$pregsearch = "/".implode("|",array_unique(explode(" ",$keywords)))."/g"; //remove dups and join as regex
$str = preg_replace($pregsearch, "<b>$0</b>", $str);
Only recomended if your searching a large string.

Explode and assign it to a multi-dimensional array

I found this code in another post which I found quite helpful but for me it's only half the equation. In line with the following code, I need to take the string from a database, explode it into the 2d array, edit values in the array and implode it back ready for storage in the same format. So specifically backwards in the same order as the existing script.
The code from the other post >>
$data = "i love funny movies \n i love stackoverflow dot com \n i like rock song";
$data = explode(" \n ", $data);
$out = array();
$step = 0;
$last = count($data);
$last--;
foreach($data as $key=>$item){
foreach(explode(' ',$item) as $value){
$out[$key][$step++] = $value;
}
if ($key!=$last){
$out[$key][$step++] = ' '; // not inserting last "space"
}
}
print '<pre>';
print_r($out);
print '</pre>';
The quoted code inserts separate array elements which just have a space as value. One can wonder what benefit those bring.
Here are two functions you could use:
function explode2D($row_delim, $col_delim, $str) {
return array_map(function ($line) use ($col_delim) {
return explode($col_delim, $line);
}, explode($row_delim, $str));
}
function implode2D($row_delim, $col_delim, $arr) {
return implode($row_delim,
array_map(function ($row) use ($col_delim) {
return implode($col_delim, $row);
}, $arr));
}
They are each other's opposite, and work much like the standard explode and implode functions, except that you need to specify two delimiters: one to delimit the rows, and another for the columns.
Here is how you would use it:
$data = "i love funny movies \n i love stackoverflow dot com \n i like rock song";
$arr = explode2D(" \n ", " ", $data);
// manipulate data
// ...
$arr[0][2] = "scary";
$arr[2][2] = "balad";
// convert back
$str = implode2D(" \n ", " ", $arr);
See it run on repl.it.

count the occurrences of all the letters in a string PHP

I want to count the frequency of occurrences of all the letters in a string. Say I have
$str = "cdcdcdcdeeeef";
I can use str_split and array_count_values to achieve this.
array_count_values(str_split($str));
Wondering if there is another way to do this without converting the string to an array? Thanks
You don't have to convert that into an array() you can use substr_count() to achieve the same.
substr_count — Count the number of substring occurrences
<?php
$str = "cdcdcdcdeeeef";
echo substr_count($str, 'c');
?>
PHP Manual
substr_count() returns the number of times the needle substring occurs in the haystack string. Please note that needle is case sensitive.
EDIT:
Sorry for the misconception, you can use count_chars to have a counted value of each character in a string. An example:
<?php
$str = "cdcdcdcdeeeef";
foreach (count_chars($str, 1) as $strr => $value) {
echo chr($strr) . " occurred a number of $value times in the string." . "<br>";
}
?>
PHP Manual: count_chars
count_chars — Return information about characters used in a string
There is a php function that returns information about characters used in a string: count_chars
Well it might not be what you are looking for, because according to http://php.net/manual/en/function.count-chars.php it
Counts the number of occurrences of every byte-value (0..255) in
string and returns it in various ways
Example from same link (http://php.net/manual/en/function.count-chars.php):
<?php
$data = "Two Ts and one F.";
foreach (count_chars($data, 1) as $i => $val) {
echo "There were $val instance(s) of \"" , chr($i) , "\" in the string.\n";
}
?>
class Strings
{
public function count_of_each_letter($string){
$string_chars = array();
$length_ = mb_strlen($string,'UTF-8');
if($length_== 0){return null;}
else{
for ($i=0; $i < $length_; $i++) {
$each_letter = mb_substr($string,0,1,'UTF-8');
$string_chars[$each_letter] = mb_substr_count($string, $each_letter);
$string = str_replace($each_letter,"", $string);
$length_ = mb_strlen($string,'UTF-8');
}
$string = '';
foreach ($string_chars as $key => $value) {
$string .= $key.'-'.$value.'<br>';
}
return $string;
}
}
}
$new_counter = new Strings();
echo $new_counter::count_of_each_letter('ختواجرایآهنگبهصورتتکنفرهنمود.اوازسال۱۹۷۲تا۱۹۷۵،۴آلبوماستودیوییتک‌نفرهمنتشرکردوحتینامزدیکجایزهاسکارهمشد.درهمینسال‌هاگروهاقدامبهبرگزاریتورکنسرتدراروپاونیزیکتورجهانیکردند.جکسونفایودرسال۱۹۷۵ازشرکتنشرموسیقیموتاونرکوردزبهسی‌بی‌اسرکوردزنقلمکانکردند.گروههمچنانبهاجراهایبین‌المللیخودادامهمی‌دادواز۱۹۷۶تا۱۹۸۴(از۱۵تا۲۴سالگیمایکل)ششآلبوماستودیوییدیگرمنتشرکرد.درهمینمدت،مایکلترانه‌سرایاصلیگروهجکسونزبود.Cantional,oderGesangbuchAugsburgischerKonfessionin1627.ohannSebastianBachcomposedafour-partsetting,BWV285,whichiswithouttext.twaspublishedasNo.196inthecollectionofchoralesbyJohannPhilippKirnbergerundCarlPhilippEmanufread');
you can do it by following way as well:
$str = 'aabbbccccdddeeedfff';
$arr = str_split($str);
$result = array_count_values($arr);
$string = http_build_query($result,'','');
echo str_replace('=','',$string);

Uppercase for first letter with php

How can I convert to uppercase for the following example :
title-title-title
Result should be:
Title-Title-Title
I tried with ucwords but it converts like this: Title-title-title
I currently have this:
echo $title = ($this->session->userdata('head_title') != '' ? $this->session->userdata('head_title'):'Our Home Page');
In this particular string example, you could explode the strings first, use that function ucfirst() and apply to all exploded strings, then put them back together again:
$string = 'title-title-title';
$strings = implode('-', array_map('ucfirst', explode('-', $string)));
echo $strings;
Should be fairly straightforward on applying this:
$title = '';
if($this->session->userdata('head_title') != '') {
$raw_title = $this->session->userdata('head_title'); // title-title-title
$title = implode('-', array_map('ucfirst', explode('-', $raw_title)));
} else {
$title = 'Our Home Page';
}
echo $title;
echo str_replace(" ","-",ucwords(str_replace("-"," ","title-title-title")));
Fiddle
Output:
Title-Title-Title
Demo
Not as swift as Ghost's but a touch more readable for beginners to see what's happening.
//break words on delimiter
$arr = explode("-", $string);
//capitalize first word only
$ord = array_map('ucfirst', $arr);
//rebuild the string
echo implode("-", $ord);
The array_map() applies callback to the elements of the given array. Internally, it traverses through the elements in our word-filled array $arr and applies the function ucfirst() to each of them. Saves you couple of lines.
Edit #2
This isn't working for the new information added to op, as there is an answer this won't be updated to reflect that.
Edit #1
$var = "title-title-title";
$var = str_replace (" ", "_", ucwords (str_replace (" ", "_", $var));
Old, non-working
$var = "title-title-title";
$var = implode("-", ucwords (explode("-", $var)));
try the following:
$str='title-title-title';
$s='';
foreach(explode('-',$str) as $si){
$s.= ($s ? "-":"").ucfirst($si);
}
$s should be Title-Title-Title at this point

Regex to transform abcd to (a(b(c(d))))

I'm using PHP's preg_replace, and trying to transform the string
abcd
into
(a(b(c(d))))
This is the best I've got:
preg_replace('/.(?=(.*$))/', '$0($1)', 'abcd');
// a(bcd)b(cd)c(d)d()
Is it even possible with regex?
Edit I've just discovered this in the PCRE spec: Replacements are not subject to re-matching, so my original approach isn't going to work. I wanted to keep it all regex because there's some more complicated matching logic in my actual use case.
How about:
preg_replace('/./s', '($0', 'abcd') . str_repeat(')', strlen('abcd'));
?
(Does that count as "with regex"?)
You can use preg_match_all. Not sure what kind of characters you want, though. So I'll give an example for all characters:
$val = 'abcd1234';
$out = '';
if(preg_match_all('#.#', $val, $matches))
{
$i = 0; // we'll use this to keep track of how many open paranthesis' we have
foreach($matches[0] as &$v)
{
$out .= '('.$v;
$i++;
}
$out .= str_repeat(")", $i);
}
else
{
// no matches found or error occured
}
echo $out; // (a(b(c(d(1(2(3(4))))))))
Will be easy to customise further, as well.
This is my way to do it =) :
<?php
$arr = str_split("abcd");
$new_arr = array_reverse($arr);
foreach ($new_arr as $a) {
$str = sprintf('(%s%s)', $a, $str);
}
echo "$str\n";
?>
KISS isn't it ? (few lines : 6)
I went with something along the lines of a combination of the above answers:
preg_match_all('/./ui', 'abcd', $matches);
$matches = $matches[0];
$string = '('.implode('(', $matches).str_repeat(')', count($matches));

Categories