Case (in)sensitive Replace for str_ireplace for search results - php

I have a list of items. I want to use them in search terms. Say the list is:
Hello, World!
The World is not Enough
Around the world in 80 days.
WAR of the WORLDS
Now, if I am searching for the keyword world (notice all are in small letters), I am giving this function.
preg_replace(/world/, '<span class="label label-search-results">$0</span>', $item);
Where the $item is each line, the output is:
Warning: preg_replace() [function.preg-replace]: Delimiter must not be alphanumeric or backslash in /myfile.php on line XX.
If I use str_ireplace(), I don't know the original case of the found text. It would be something like:
str_ireplace("world", '<span class="label label-search-results">world</span>', $item);
And that results in all the world, World and WORLD being in lower case. Any ideas on how to preserve the case after replace?

That's the perfect use case for preg_replace_callback(), just use it like this:
echo preg_replace_callback("/" . preg_quote($_GET["q"], "/") . "/i", function($m){
return "<span class='label label-search-results'>" . $m[0] . "</span>";
}, $item);

preg_replace('/(world)/i', '<span class="label label-search-results">$1</span>', $item);
Try with the flag i for case-insensitivity.

Related

PHP: add a linebreaks in a preg replace

I can understand most PHP code by just reading it, but I've never understood how preg_replace is used, so I've only been copying other peoples codes to get what I want.
Now I need to add linebreaks in it, and I've tried multiple combinations but I can't figure out how to use it.
This is my current code:
$textbr = nl2br($text);
$output = preg_replace_callback('/([.!?])\s*(\w)/', function ($matches) {
return strtoupper($matches[1] . ' ' . $matches[2]);
}, ucfirst(strtolower($textbr)));
echo substr($output,0,870);
echo "...</p>";
So how would I add line breaks in this part of the code? I need it to both output the linebreak but then make the next letter a capitalized one.
Line breaks are: \n for NewLine, and \r for Return carriage.
RegExp is fun, I advise learning more about it http://www.regular-expressions.info/ :)
To anyone wondering. I solved it by just randomly trying myself towards the solution.
SOLUTION:
$textbr = nl2br($text);
$output = preg_replace_callback(
'/([.!?\r?\n)])\s*(\w)/',
function ($matches) {
return strtoupper($matches[1] . ' ' . $matches[2]);
},
ucfirst(
strtolower($textbr)
)
);

Split variable content into multiple paragraphs

Hey there,
I have this little php code:
<p class="category_text"><? echo $category_text; ?></p>
I waht to split the $category_text and get something like this:
This is sentence 1 of category_text
This is sentence 2 of category_text
and so on...
$category_text has about 300 words and lets say 6 sentences. How could I split the text in multiple paragraphs (delimited by the stop sings ".")
Thank you very much!
echo '<p class="category_text">'
. implode('</p><p class="category_text">', explode('.',$string))
.'</p>';
You can just replace the "." by the tag "":
<p class="category_text"><? echo str_replace('.', '.<br />', $category_text); ?></p>
It's not a perfect solution! But if you text is simple enough this little trick should work.
For example if you have a line with 3 dots:
$category_text = "Ok...";
It will show up like that:
OK.
.
.
Also if your sentences finish by "?" or "!" you can also use that:
<p class="category_text"><? echo str_replace(array('.', '!', '?'), array('.<br />', '!<br />', '?<br />'), $category_text); ?></p>
PS: My solution will create one paragraph "" but with multiple line break
Try creating an array, and then output the lines one by one. A sentence ending in ... would still be recognized as still ends in ". ".
$sentences = explode('. ', $category_text)
foreach($sentences as $val)
{
echo $val . ".<br /><br />";
}
You want to split a text into sentences, which is not trivial - using explode(".", $string) does often not give good results.
Search Stackoverflow for "php split sentence", or directly try the solution to PHP: Parse document / text into sentences :
http://www.zubrag.com/scripts/text-splitter.php
Once you have an array with sentences, use
echo '<p>' . implode('</p><p>', $sentences) . '</p>';
to echo them out.

preg_replace between > and <

I have this:
<div> 16</div>
and I want this:
<div><span>16</span></div>
Currently, this is the only way I can make it work:
preg_replace("/(\D)(16)(\D)/", "$1<span>$2</span>$3", "<div> 16</div>")
If I leave off the $3, I get:
<div><span>16</span>/div>
Not quite sure what your after, but the following is more generic:
$value = "<div> 16 </div>";
echo(preg_replace('%(<(\D+)[^>]*>)\s*([^\s]*)\s*(</\2>)%', '\1<span>\3</span>\4', $value));
Which would result in:
<div><span>16</span></div>
Even if the value were:
<p> 16 </div>
It would result in:
<p><span>16</span></p>
I think you meant to say you're using the following:
print preg_replace("/(\\D+)(16)(\\D+)/", "$1<span>$2</span>$3", "<div>16</div>");
There's nothing wrong with that. $3 is going to contain everything matched in the second (\D+) group. If you leave it off, obviously it's not going to magically appear.
Note that your code in the question had some errors:
You need to escape your \'s in a string.
You need to use \D+ to match multiple characters.
You have a space before 16 in your string, but you're not taking this into account in your regex. I removed the space, but if you want to allow for it you should use \s* to match any number of whitespace characters.
The order of your parameters was incorrect.
Try following -
$str = "<div class=\"number\"> 16</div>";
$formatted_str = preg_replace("/(<div\b[^>]*>)(.*?)<\/div>/i", "$1<span>$2</span></div>", $s);
echo $formatted_str;
This is what ended up working the best:
preg_replace('/(<.*>)\s*('. $page . ')\s*(<.*>)/i', "$1" . '<span class="curPage">' . "$2" . '</span>' . "$3", $pagination)
What I found was that I didn't know for sure what tags would precede or follow the page number.

preg_replace() in PHP - Replacing n-occurrences of a character with n-occurrences of another, when following a new line

I'm looking to replace all occurrences of space characters that follow a new line (or occur at the beginning of the input string). I know that I can achieve this using preg_replace_callback() with a callback that uses str_repeat and strlen, or similarly with the /e switch; but was wondering if it could be done more simply.
Currently I have the following:
$testData = " Hello\n to everybody\n in the world";
echo preg_replace('/^|\n( )+/', ' ', $pValue);
which gives:
" Hello to everybody in the world"
What I'm really after is:
" Hello\n to everybody\n in the world"
I should have searched harder before asking: found the answer (for a java solution) that seems to work perfectly. I'll leave the solution here for the sake of anybody else that has the same problem.
$testData = " Hello\n to everybody\n in the world";
echo preg_replace('/(?m)(?:^|\\G) /', ' ', $pValue);
Now just need to identify whether older versions of PHP support this.
You can use recursion
$pValue = " Hello\n to everybody\n in the world";
echo myReplace($pValue);
function myReplace($value)
{
$value = preg_replace('/(^|\\n)(( )*) /', '\1\2 ', $value);
if (preg_match('/(^|\\n)(( )*) /', $value))
{
$value = myReplace($value);
}
return $value;
}

preg_replace_callback() memory issue

i'm having a memory issue while testing a find/replace function.
Say the search subject is:
$subject = "I wrote an article in the A+ magazine.
It'\s very long and full of words.
I want to replace every A+ instance in this text by a link
to a page dedicated to A+.";
the string to be found :
$find='A+';
$find = preg_quote($find,'/');
the replace function callback:
function replaceCallback($match)
{
if (is_array($match)) {
return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>';
}
}
and the call:
$result = preg_replace_callback($find, 'replaceCallback', $subject);
now, the complete searched pattern is drawn from the database. As of now, it is:
$find = '/(?![^<]+>)\b(voice recognition|test project reference|test|synesthesia|Superflux 2007|Suhjung Hur|scripts|Salvino a. Salvaggio|Professional Lighting Design Magazine|PLDChina|Nicolas Schöffer|Naziha Mestaoui|Nabi Art Center|Markos Novak|Mapping|Manuel Abendroth|liquid architecture|LAb[au] laboratory for Architecture and Urbanism|l'Arca Edizioni|l' ARCA n° 176 _ December 2002|Jérôme Decock|imagineering|hypertext|hypermedia|Game of Life|galerie Roger Tator|eversion|El Lissitzky|Bernhard Tschumi|Alexandre Plennevaux|A+)\b/s';
This $find pattern is then looked for (and replaced if found) in 23 columns across 7 mysql tables.
Using the suggested preg_replace() instead of preg_replace_callback() seems to have solved the memory issue, but i'm having new issues down the path: the subject returned by preg_replace() is missing a lot of content...
UPDATE:
the content loss is due to using preg_quote($find,'/');
It now works, except for... 'A+' which becomes 'A ' after the process.
I'm trying to reproduce your error but there's a parse error that needs to be fixed first. Either this isn't enough code to be a good sample or there's genuinely a bug.
First of all, the value you store in $find is not a pull pattern - so I had to add pattern delimiters.
Secondly, your replace string doesn't include the closing element for the anchor tags.
$subject = "
I wrote an article in the A+ magazine. It'\s very long and full of words. I want to replace every A+ instance in this text by a link to a page dedicated to A+.
";
$find='A+';
$find = preg_quote($find,'/');
function replaceCallback($match)
{
if (is_array($match)) {
return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>';
}
}
$result = preg_replace_callback( "/$find/", 'replaceCallback', $subject);
echo $result;
This code works, but I'm not sure it's what you want. Also, I have have strong suspicion that you don't need preg_replace_callback() at all.
This here works for me, i had to change the preg match a bit but it turns every A+ for me into a link. You also are missing a </a> at the end.
$subject = "I wrote an article in the A+ magazine. It'\s very long and full of words. I want to replace every A+ instance in this text by a link to a page dedicated to A+.";
function replaceCallback($match)
{
if (is_array($match))
{
return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>';
}
}
$result = preg_replace_callback("/A\+/", "replaceCallback", $subject);
echo $result;
Alright - I can see, now, why you're using the callback
First of all, I'd change your callback to this
function replaceCallback( $match )
{
if ( is_array( $match ) )
{
$htmlVersion = htmlspecialchars( $match[1], ENT_COMPAT, 'UTF-8' );
$urlVersion = urlencode( $match[1] );
return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion. '">' . $htmlVersion . '</a>';
}
return $match;
}
The stripslashes commands aren't going to do you any good.
As far as addressing the memory issue, you may want to break down your pattern into multiple patterns and execute them in a loop. I think your match is just too big/complex for PHP to handle it in a single call cycle.

Categories