PHP get some string within a specific words - php

I want to ask about is it possible to get some string that between a specifi keyword? For example, I have 2 sentence like these:
I will go to #new bathroom and wash the car#
Result: bathroom and wash the car
Someone need an #new icebreaker# to hold that problem
Result : icebreaker
I want to make condition to get all words between the #new #
Any idea how to create this?
My code so far:
<?php
$sentence = "I will go to #new bathroom and wash the car#";
$start = strpos($sentence, "#new");
//$end = strpos($sentence, "#");
$end = 20; //because my strpos still wrong, I define a static number
$new = substr($sentence, $start, $end);
echo $new;
?>
My problem is I can't find a way to chase the last hashtag

Use this regular expression:
/#new (.+)#/i
Together with preg_match(), you'll get your match in an array:
<?php
$string = "Someone need an #new icebreaker# to hold that problem";
preg_match("/#new (.+)#/i", $string, $matches);
var_dump($matches[1]); // icebreaker
Demo
If you anticipate more than one possible match, use preg_match_all() to get them all.

I have written the following code for your problem but please bare in mind that i am still a beginner myself.
It works exactly how you want it to but i am sure there are better solutions out there.
<?php
$string = "I will go to #new bathroom and wash the car#";
$stringArray = str_split($string);
$output = '';
$count = 0;
foreach($stringArray as $letter){
if($count == 0 && $letter == '#'){
$count = 1;
} elseif($count == 1){
if($letter != '#'){
$output .= $letter;
} else {
$count = 2;
}
}
}
echo $output;
?>
hope this helps :)

Another way different to Regular Expression is to explode the string and replace the new in the sentence
This will just work if you have only one keyword in the sentence #new
$string = "I will go to #new bathroom and wash the car#";
$string1 = "Someone need an #new icebreaker# to hold that problem";
function getString($string, $delimiter = '#')
{
$string_array = explode($delimiter, $string);
return str_replace('new ', '', $string_array[1]);
}
echo getString($string);
//bathroom and wash the car
echo getString($string1);
//icebreaker
I'd like more work with arrays
$string = [
"I will go to #new bathroom and wash the car#",
"Someone need an #new icebreaker# to hold that problem"
];
function getString($string, $delimiter = '#')
{
$result = [];
foreach ($string as $value) {
$string_array = strstr($value, $delimiter) ? explode($delimiter, $value) : [];
$result[] = isset($string_array[1]) ? str_replace('new ', '', $string_array[1]) : NULL;
}
return $result;
}
print_r(getString($string));
/*
Array
(
[0] => bathroom and wash the car
[1] => icebreaker
)
*/

You can use regex to match that. here is a links and a simple regex.
(#)\w+(#)
(\#)+(.)+(\#)
https://regexr.com/
http://php.net/manual/en/function.preg-match.php

You can search "#" from end,
like $end = strpos($sentence, "#", -0);
and than get substring as you already have.
$new = substr($sentence, $start, $end);

Related

Delete words that match the pattern on the string

I have to filter a string according to words similar to the pattern.
I need to delete words that match the formula:
<?php
$string = 'armin van burren yummy';
$pattern = 'a%n v%n b%n';
//result: Yummy
$string = 'Beyonce - love on top';
$pattern = 'b%e';
//result: Love on top
$string = 'Ed Sheeran - Shape of You';
$pattern = 'e_ s_____n';
//result: Shape of You
?>
Do you have any idea how to get this result, maybe there is some function in php. I tried to search, unfortunately I didn't find any information. Thank you for all the help and examples
This code works for me, is it possible to limit the amount of foreach for this code (performance is concerned)?
function filterlike($arr, $like){
if ($arr && $like){
$like = preg_replace('/_{1,}/','.*', $like);
$like = preg_replace('/%/','.*', $like);
$like = explode(' ', $like);
$filter = array();
foreach ($arr as $a){
foreach ($like as $l){
$a = preg_replace('/'.$l.'/', '', $a);
}
$filter[] = $a;
}
return $filter;
}
}
print_r(filterlike(array('armin', 'van', 'burren', 'jummy'), 'a%n v%n b%n'));
print_r(filterlike(array('armin', 'van', 'burren', 'jummy'), 'a___n v_n b____n'));

Php search replacer

I have a search String: $str (Something like "test"), a wrap string: $wrap (Something like "|") and a text string: $text (Something like "This is a test Text").
$str is 1 Time in $text. What i want now is a function that will wrap $str with the wrap defined in $wrap and output the modified text (even if $str is more than one time in $text).
But it shall not output the whole text but just 1-2 of the words before $str and then 1-2 of the words after $str and "..." (Only if it isn`t the first or last word). Also it should be case insensitive.
Example:
$str = "Text"
$wrap = "<span>|</span>"
$text = "This is a really long Text where the word Text appears about 3 times Text"
Output would be:
"...long <span>Text</span> where...word <span>Text</span> appears...times <span>Text</span>"
My Code (Obviusly doesnt works):
$tempar = preg_split("/$str/i", $text);
if (count($tempar) <= 2) {
$result = "... ".substr($tempar[0], -7).$wrap.substr($tempar[1], 7)." ...";
} else {
$amount = substr_count($text, $str);
for ($i = 0; $i < $amount; $i++) {
$result = $result.".. ".substr($tempar[$i], -7).$wrap.substr($tempar[$i+1], 0, 7)." ..";
}
}
If you have a tipp or a solution dont hesitate to let me know.
I have taken your approach and made it more flexible. If $str or $wrap changes you could have escaping issues within the regex pattern so I have used preg_quote.
Note that I added $placeholder to make it clearer, but you can use $placeholder = "|" if you don't like [placeholder].
function wrapInString($str, $text, $element = 'span') {
$placeholder = "[placeholder]"; // The string that will be replaced by $str
$wrap = "<{$element}>{$placeholder}</{$element}>"; // Dynamic string that can handle more than just span
$strExp = preg_quote($str, '/');
$matches = [];
$matchCount = preg_match_all("/(\w+\s+)?(\w+\s+)?({$strExp})(\s+\w+)?(\s+\w+)?/i", $text, $matches);
$response = '';
for ($i = 0; $i < $matchCount; $i++) {
if (strlen($matches[1][$i])) {
$response .= '...';
}
if (strlen($matches[2][$i])) {
$response .= $matches[2][$i];
}
$response .= str_replace($placeholder, $matches[3][$i], $wrap);
if (strlen($matches[4][$i])) {
$response .= $matches[4][$i];
}
if (strlen($matches[5][$i]) && $i == $matchCount - 1) {
$response .= '...';
}
}
return $response;
}
$text = "text This is a really long Text where the word Text appears about 3 times Text";
string(107) "<span>text</span> This...long <span>text</span> where...<span>text</span> appears...times <span>text</span>"
To make the replacement case insensitive you can use the i regex option.
If I understand your question correct, just a little bit of implode and explode magic needed
$text = "This is a really long Text where the word Text appears about 3 times Text";
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
If you specifically need to render the span tags using HTML, just write it that way
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
Use patern below to get your word and 1-2 words before and after
/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i
demo
In PHP code it can be:
$str = "Text";
$wrap = "<span>|</span>";
$text = "This is a really long Text where the word Text appears about 3 times Text";
$temp = str_replace('|', $str, $wrap); // <span>Text</span>
// find patern and 1-2 words before and after
// (to make it casesensitive, delete 'i' from patern)
if(preg_match_all('/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i', $text, $match)) {
$res = array_map(function($x) use($str, $temp) { return '... '.str_replace($str, $temp, $x) . ' ...';}, $match[0]);
echo implode(' ', $res);
}

php extract a sub-string before and after a character from a string

need to extract an info from a string which strats at 'type-' and ends at '-id'
IDlocationTagID-type-area-id-492
here is the string, so I need to extract values : area and 492 from the string :
After 'type-' and before '-id' and after 'id-'
You can use the preg_match:
For example:
preg_match("/type-(.\w+)-id-(.\d+)/", $input_line, $output_array);
To check, you may need the service:
http://www.phpliveregex.com/
P.S. If the function preg_match will be too heavy, there is an alternative solution:
$str = 'IDlocationTagID-type-area-id-492';
$itr = new ArrayIterator(explode('-', $str));
foreach($itr as $key => $value) {
if($value === 'type') {
$itr->next();
var_dump($itr->current());
}
if($value === 'id') {
$itr->next();
var_dump($itr->current());
}
}
This is what you want using two explode.
$str = 'IDlocationTagID-type-area-id-492';
echo explode("-id", explode("type-", $str)[1])[0]; //area
echo trim(explode("-id", explode("type-", $str)[1])[1], '-'); //492
Little Simple ways.
echo explode("type-", explode("-id-", $str)[0])[1]; // area
echo explode("-id-", $str)[1]; // 492
Using Regular Expression:
preg_match("/type-(.*)-id-(.*)/", $str, $output_array);
print_r($output_array);
echo $area = $output_array[1]; // area
echo $fnt = $output_array[2]; // 492
You can use explode to get the values:
$a = "IDlocationTagID-type-area-id-492";
$data = explode("-",$a);
echo "Area ".$data[2]." Id ".$data[4];
$matches = null;
$returnValue = preg_match('/type-(.*?)-id/', $yourString, $matches);
echo($matches[1]);

How to check whether pattern is matched by using preg_replace only

Currently, I have the following code, which use to perform pattern matching & pattern replacing.
<?php
function fun($text) {
if (preg_match("/^(ATE|EAT)\s+(\S+).*/", $text)) {
$text = preg_replace("/^(ATE|EAT)\s+(\S+).*/", "EAT $2", $text);
} else {
$text = preg_replace("/.*(ATE|EAT).*/", "EAT", $text);
}
return $text;
}
// EAT pizza
echo fun('EAT pizza') . "\n";
// EAT pizza
echo fun('EAT pizza at paris') . "\n";
// EAT
echo fun('I EAT pizza at paris') . "\n";
I feel the above code is not optimized, as I'm performing preg_match before preg_replace. I feel this is redundant.
I tried to check the returned string from preg_replace
<?php
function fun($text) {
$tmp = preg_replace("/^(ATE|EAT)\s+(\S+).*/", "EAT $2", $text);
// I don't think this is the correct way to check for "Not Match" ?!
if ($tmp === $text) {
$tmp = preg_replace("/.*(ATE|EAT).*/", "EAT", $text);
}
return $tmp;
}
// EAT pizza
echo fun('EAT pizza') . "\n";
// EAT pizza
echo fun('EAT pizza at paris') . "\n";
// EAT
echo fun('I EAT pizza at paris') . "\n";
However, fun('EAT pizza') will fail, as it will print out EAT instead of expected EAT pizza.
Is there a correct way to optimize the above code?
I assume all you actually ask for is to know how to know if there where any replacements in your preg_replace since it is quite unclear what you actually want to achieve.
From the PHP Documentation on preg-replace:
Description
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
[..]
count
If specified, this variable will be filled with the number of replacements done.
So if you add a count to your preg_replace, you'll get the number of replacements, thus the number of occurances.
Example given (thou this is kind of into the blue due to lack of information):
function fun($text) {
$count = 0;
$tmp = preg_replace("/^(ATE|EAT)\s+(\S+).*/", "EAT $2", $text, -1, $count);
if ($count == 0) {
$tmp = preg_replace("/.*(ATE|EAT).*/", "EAT", $text);
}
return $tmp;
}
So this will replace ATE <something> or EAT <something> with EAT <something>, or, if neither of those where found, it will attempt to replace ATE or EAT with EAT.
Try with following function:
function fun($text) {
$tmp = str_replace('ATE', 'EAT', $text);
$pos = strpos($text, 'EAT');
if ($pos < 0) {
return $text;
} else if ($pos > 0) {
$tmp = preg_replace('/^.*?EAT/', 'EAT', $tmp);
}
$tmp = preg_replace("/^EAT\s+(\S+).*/", "EAT $2", $tmp);
return $tmp;
}

How do I return a part of text with a certain word in the middle?

If this is the input string:
$input = 'In biology (botany), a "fruit" is a part of a flowering
plant that derives from specific tissues of the flower, mainly one or
more ovaries. Taken strictly, this definition excludes many structures
that are "fruits" in the common sense of the term, such as those
produced by non-flowering plants';
And now I want to perform a search on the word tissues and consequently return only a part of the string, defined by where the result is, like this:
$output = '... of a flowering plant that derives from specific tissues of the flower, mainly one or more ovaries ...';
The search term may be in the middle.
How do I perform the aforementioned?
An alternative to my other answer using preg_match:
$word = 'tissues'
$matches = array();
$found = preg_match("/\b(.{0,30}$word.{0,30})\b/i", $string, $matches);
if ($found == 0) {
// string not found
} else {
$output = $matches[1];
}
This may be better as it uses word boundaries.
EDIT: To surround the search term with a tag, you'll need to slightly alter the regex. This should do it:
$word = 'tissues'
$matches = array();
$found = preg_match("/\b(.{0,30})$word(.{0,30})\b/i", $string, $matches);
if ($found == 0) {
// string not found
} else {
$output = $matches[1] . "<strong>$word</strong>" . $matches[2];
}
User strpos to find the location of the word and substr to extract the quote. For example:
$word = 'tissues'
$pos = strpos($string, $word);
if ($pos === FALSE) {
// string not found
} else {
$start = $pos - 30;
if ($start < 0)
$start = 0;
$output = substr($string, $start, 70);
}
Use stripos for case insensitive search.

Categories