Count spaces within exploded quotations - php

In simplest terms im trying to change the data string if more than 4 spaces are found within quotations. I'm able to do this on a simple string but not within exploded quotes as it becomes an array which count functions wont accept. Is there a regex to do what im looking for in this case or something?
$data = 'Hello World "This is a test string! Jack and Jill went up the hill."';
$halt = 'String had more than 4 spaces.';
$arr = explode('"', $data);
if (substr_count($arr, ' ') >= 4) {
$data = implode('"', $arr);
$data = $halt;

As far as I understand your request, this will do the job
$data = 'Hello World "This is a test string! Jack and Jill went up the hill."';
$halt = 'String had more than 4 spaces.';
// split $data on " and captures them
$arr = preg_split('/(")/', $data, -1, PREG_SPLIT_DELIM_CAPTURE);
// must we count spaces ?
$countspace = 0;
foreach ($arr as $str) {
// swap $countspace when " is encountered
if ($str == '"') $countspace = !$countspace;
// we have to count spaces
if ($countspace) {
// more than 4 spaces
if (substr_count($str, ' ') >= 4) {
// change data
$data = $halt;
break;
}
}
}
echo $data,"\n";
output:
String had more than 4 spaces.

If you define:
function count_spaces($str) {return substr_count($str, ' '); }
you can then use array_sum(array_map("count_spaces", $arr)) to count all of the spaces in all of the strings in $arr.

Related

How can I move chinese characters in a string to the end of string?

I have a string like this now: I want to do the following in PHP:
$string = 'Testing giving dancing 喝 喝 passing 制图 giving 跑步 吃';
I want to move all Chinese characters to the end of the string, and also reversing their current order. Accordingly, Removing the duplicate English words and Return the modified string
Here you go! Check the comments in the code:
<?php
$string = 'Testing giving dancing 喝 喝 passing 制图 giving 跑步 吃';
// split by a space into an array
$explosion = explode(' ', $string);
$normalWords = [];
$chineseWords = [];
// loop through the array
foreach ($explosion as $debris) {
// if not normal alphabet characters
if (!preg_match('#[a-zA-Z]+#', $debris) && !in_array($debris, $chineseWords)) {
// add to chinese words array if not already in the array
$chineseWords[] = $debris;
} elseif (preg_match('#[a-zA-Z]+#', $debris) && !in_array($debris, $normalWords)) {
// add to normal words array if not already in the array
$normalWords[] = $debris;
}
}
// reverse the chinese characters like you wanted
$chineseWords = array_reverse($chineseWords);
// Piece it all back together
$string = implode(' ', $normalWords) . ' ' . implode(' ', $chineseWords);
// and output
echo $string; // Testing giving dancing passing 吃 跑步 制图 喝
See it here! https://3v4l.org/FWQWG

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.

Make string shorter. Cut it by the last word [duplicate]

This question already has answers here:
Get first 100 characters from string, respecting full words
(18 answers)
Closed 8 years ago.
How to make string shorter by cut it on the last word?
like example, allowed symbols are 10, and echo only these words which fits in this limit.
$string = 'Hello Hello John Doe'
// Limit 10. Expected result:
$string = 'Hello'
// Limit 12. Expected result:
$string = 'Hello Hello'
...
All I can find in manual is cutting string by symbols, not by words. There are some custom functions to do so, but maybe there are php command for this?
This should work:
$str = "i have google too";
$strarr = explode(" ", $str);
$res = "";
foreach($strarr as $k)
{
if (strlen($res.$k)<10)
{
$res .= $k." ";
}
else
{
break;
};
}
echo $res;
http://codepad.org/NP9t4IRi
Tried to edit Mike's answer, to fix the last word thing, but was not able to.
So here is his solution with the fix:
$str = "Hello Hello My name is Hal";
$len = 10;
if ( strlen( $str ) > $len )
{
$out = substr($str,0,$len);
if ( $str[$len] != ' ')
{
$out = substr($out,0,strrpos($out,' '));
}
}
echo $out; // Hello
Edit: update version to cope with word breaks better.
This shouldn't be too difficult. Truncate to the maximum length, then truncate to the last space. Add an adjustment for lengths that fall on the end of words
<?php
$str = "Hello Hello My name is Hal";
for ($i = 3; $i <30;$i++) {
echo "'".trunc($str,$i)."'\n";
}
function trunc($str, $len) {
$str.=' ';
$out = substr($str,0,$len+1);
$out = substr($out,0,strrpos($out,' '));
return trim($out);
}
Here's a codepad version

How to scan text for multiple strings in php

In php, how do you scan text (in the form of user submitted messages) for multiple strings (in the form of other user names)?
Example, below a user submits a message, I want a way to "find" the strings 'user-one' and 'user-two' and send those strings into an array.
Hello this is a test message, can you see it #user-one, #user-two?
You can try
$message = "Hello this is a test message, can you see it #user-one, #user-two?" ;
preg_match_all("/\#[a-z\-]+/", $message,$match);
var_dump($match[0]);
Output
array (size=2)
0 => string '#user-one' (length=9)
1 => string '#user-two' (length=9)
preg_match_all('|\#(.*) |' , $userText , $match);
print_r($match[1])
$match[1] will contain all usernames. $userText is the users input text. Use $match[0] if you want usernames with the #.
You can use strrpos to retrieve a position and substr + strlen to get the text.
Example:
...
$mystring = "Hello this is a test message, can you see it #user-one, #user-two?";
$pos = strrpos($mystring, "#user-one");
if ($pos > 0) {
$str = substr($mystring, $pos, strlen("#user-one"));
}
...
Sorry if I don't understand correctly the question.
No messy pattern match with this!
function stringToUserArray($str) {
$remove = array(".",",","!","?");
$str = str_replace($remove, " ", $str);
$array = explode(" ", $str);
foreach($array as $string) {
if($string[0] == "#") {
$users[] = $string;
}
}
return $users;
}

Categories