My question is exactly opposite to this one i added last night .
Need to remove the last br tag.
Input:
Test1 is here<br><br>Now comes Test2<br><br>Then test 3<br><br><br>Thats it.
Output
Test1 is here<br>Now comes Test2<br>Then test 3<br><br>Thats it.
My try:
preg_replace("[((?:<br>)+)]","",$posttext)
It removes all breaks.
You can substitute
<br><br>(?!<br)
to <br>
preg_replace('/<br><br>(?!<br)/', "<br>", $posttext);
The lookahead will prevent to match any more <br>
See demo at regex101
Feast your eyes on this hahaha
If Preg replace doesn't work...
// cuts off one <br> as high as whatever $i is at
$string = "Test1 is here<br><br>Now comes Test2<br><br>Then test 3<br><br><br>Thats it.";
$i = 10;
while($i > 0)
{
$ii = 1;
$brake = "<br>";
$replace = "";
while($ii < $i)
{
$brake .= "<br>";
$replace .= "<br>";
$ii++;
}
$string = str_replace($brake,$replace,$string);
$i--;
}
echo $string; // Test1 is here<br>Now comes Test2<br>Then test 3<br><br>Thats it.
PS: If theres no preg replace for this, it is usable albeit very inefficent.
Related
This question already has answers here:
Explode a paragraph into sentences in PHP
(8 answers)
Closed 9 years ago.
I would like to add span tag for every sentence which ended with "."
like:
my string:
"I could not have said, ’Betrayest thou the Son of man with a kiss?’ unless I believed in betrayal. The whole message of the crucifixion was simply that I did not."
O/P:
"<span id="s1">I could not have said, ’Betrayest thou the Son of man with a kiss?’ unless I believed in betrayal.</span> <span id="s2">The whole message of the crucifixion was simply that I did not.</span>"
how it possible with php?
You could do
<?php
$string="I could not have said, ’Betrayest thou the Son of man with a kiss?’ unless I believed in betrayal. The whole message of the crucifixion was simply that I did not.";
$output=str_replace(". ",'. </span> <span id="s2">',$string);
echo '<span id="s1">'.$output.'</span>';
?>
Edit Based on Comments
This version will make sure every new replacement gets a new span id
<?php
$string="I could not have said, ’Betrayest thou the Son of man with a kiss?’ unless I believed in betrayal. The whole message of the crucifixion was simply that I did not. Testing 123. testing again.";
$dots=substr_count($string,". ");
for($i=2;$i<=$dots+2;$i++)
{
$string=preg_replace("/\. /", ".</span> <span id =\"s$i\">" ,$string,1);
}
echo '<span id="s1">'.$string.'</span>';
?>
If you explode the sentence with ". ". I want to modify the code above.
$newText = "";
$count = 0;
foreach (explode(". ",$theText) as $part) {
if(ctype_upper($part{0}))
{
$count++;
$newText .= "<span id=\"s$count\">$part</span>";
}
}
I hope it should work for abbreviations or something.
Try this code,
You will get unique id for span tag.
<?php
$str = "I could not have said, 'Betrayest thou the Son of man with a kiss?' unless I believed in betrayal. The whole message of the crucifixion was simply that I did not.";
$exp_str = explode(". ",$str);
$sentence = "<span id=\"s1\">";
$n = 2;
foreach($exp_str as $val) {
$sentence .= $val.".</span> <span id=\"s$n\">";
$n++;
}
$n = $n-1;
$sentence = substr($sentence,0,strpos($sentence,".</span> <span id=\"s$n\">"));
echo $sentence;
?>
I'm not sure if preg_replace can do this (because of the unique IDs). Otherwise it can be manually done like this:
$newText = "";
$count = 0;
foreach (explode(".",$theText) as $part) {
$count++;
$newText .= "<span id=\"s$count\">$part</span>";
}
But what about periods mid sentence, as in abbreviations or something? You could probably replace the explode with a preg_split to get a better result. For instance only split if the char right after the period is not a letter or another period.
preg_split("/\.[^\,\w]/",$theText);
Or just ensure the next char is a whitespace.
preg_split("/\.\s/",$theText);
Probably a simple problem here, but I cannot find it.
I am exploding a string that was input and stored from a textarea. I use nl2br() so that I can explode the string by the <br /> tag.
The string explodes properly, but when I try to get the first character of the string in a while loop, it only returns on the first line.
Note: The concept here is greentexting, so if you are familiar with that then you will see what I am trying to do. If you are not, I put a brief description below the code sample.
Code:
while($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
$comment = nl2br($row['comment']);
$sepcomment = explode("<br />", $comment);
$countcomment = count($sepcomment);
$i = 0;
//BEGIN GREENTEXT COLORING LOOP
while($i < $countcomment) {
$fb = $sepcomment[$i];
$z = $fb[0]; // Check to see if first character is >
if ($z == ">") {
$tcolor = "#789922";
}
else {
$tcolor = "#000000";
}
echo '<font color="' . $tcolor . '">' . $sepcomment[$i] . '</font><br>';
$i++;
}
//END GREENTEXT COLORING LOOP
}
Greentext: If the first character of the line is '>' then the color of that entire line becomes green. If not, then the color is black.
Picture:
What I have tried:
strip_tags() - Thinking that possibly the tags were acting as the first characters.
$fb = preg_replace("/(<br\s*\/?>\s*)+/", "", $sepcomment[$i]);
str_replace()
echo $z //Shows the correct character on first line, blank on following lines.
$z = substr($fb, 0, 1);
Here is a test I just did where I returned the first 5 characters of the string.
Any ideas for getting rid of those empty characters?
Try "trim" function
$fb = trim($sepcomment[$i]);
http://php.net/manual/en/function.trim.php
(probably line breaks are the problem, there are \n\r characters after tag)
I have a simple text with HTML tags, for example:
Once <u>the</u> activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, <i>only</i> while the activity is in the resumed state can the <b>lifecycle</b> of a <hr/> fragment change independently.
I need to replace some parts of this text ignoring its html tags when I do this replace, for example this string - Thus, <i>only</i> while I need to replace with my string Hello, <i>its only</i> while . Text and strings to be replaced are dynamically. I need your help with my preg_replace pattern
$text = '<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text';
$arrayKeys= array('Some html' => 'My html', 'and there' => 'is there', 'in this text' => 'in this code');
foreach ($arrayKeys as $key => $value)
$text = preg_replace('...$key...', '...$value...', $text);
echo $text; // output should be: <b>My html</b> tags with <u>is</u> there are a lot of tags <i>in</i> this code';
Please help me to find solution. Thank you
Basically we're going to build dynamic arrays of matches and patterns off of plain text using Regex. This code only matches what was originally asked for, but you should be able to get an idea of how to edit the code from the way I've spelled it all out. We're catching either an open or a close tag and white space as a passthru variable and replacing the text around it. This is setup based on two and three word combinations.
<?php
$text = '<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text';
$arrayKeys= array(
'Some html' => 'My html',
'and there' => 'is there',
'in this text' =>'in this code');
function make_pattern($string){
$patterns = array(
'!(\w+)!i',
'#^#',
'! !',
'#$#');
$replacements = array(
"($1)",
'!',
//This next line is where we capture the possible tag or
//whitespace so we can ignore it and pass it through.
'(\s?<?/?[^>]*>?\s?)',
'!i');
$new_string = preg_replace($patterns,$replacements,$string);
return $new_string;
}
function make_replacement($replacement){
$patterns = array(
'!^(\w+)(\s+)(\w+)(\s+)(\w+)$!',
'!^(\w+)(\s+)(\w+)$!');
$replacements = array(
'$1\$2$3\$4$5',
'$1\$2$3');
$new_replacement = preg_replace($patterns,$replacements,$replacement);
return $new_replacement;
}
foreach ($arrayKeys as $key => $value){
$new_Patterns[] = make_pattern($key);
$new_Replacements[] = make_replacement($value);
}
//For debugging
//print_r($new_Patterns);
//print_r($new_Replacements);
$new_text = preg_replace($new_Patterns,$new_Replacements,$text);
echo $new_text."\n";
echo $text;
?>
Output
<b>My html</b> tags with <u>is</u> there are a lot of tags <i>in</i> this code
<b>Some html</b> tags with <u>and</u> there are a lot of tags <i>in</i> this text
Here we go. this piece of code should work, assuming you're respecting only twp constraints :
Pattern and replacement must have the same number of words. (Logical, since you want to keep position)
You must not split a word around a tag. (<b>Hel</b>lo World won't work.)
But if these are respected, this should work just fine !
<?php
// Splits a string in parts delimited with the sequence.
// '<b>Hey</b> you' becomes '~-=<b>~-=Hey~-=</b>~-= you' that make us get
// array ("<b>", "Hey" " you")
function getTextArray ($text, $special) {
$text = preg_replace ('#(<.*>)#isU', $special . '$1' . $special, $text); // Adding spaces to make explode work fine.
return preg_split ('#' . $special . '#', $text, -1, PREG_SPLIT_NO_EMPTY);
}
$text = "
<html>
<div>
<p>
<b>Hey</b> you ! No, you don't have <em>to</em> go!
</p>
</div>
</html>";
$replacement = array (
"Hey you" => "Bye me",
"have to" => "need to",
"to go" => "to run");
// This is a special sequence that you must be sure to find nowhere in your code. It is used to split sequences, and will disappear.
$special = '~-=';
$text_array = getTextArray ($text, $special);
// $restore is the array that will finally contain the result.
// Now we're only storing the tags.
// We'll be story the text later.
//
// $clean_text is the text without the tags, but with the special sequence instead.
$restore = array ();
for ($i = 0; $i < sizeof ($text_array); $i++) {
$str = $text_array[$i];
if (preg_match('#<.+>#', $str)) {
$restore[$i] = $str;
$clean_text .= $special;
}
else {
$clean_text .= $str;
}
}
// Here comes the tricky part.
// We wanna keep the position of each part of the text so the tags don't
// move after.
// So we're making the regex look like (~-=)*Hey(~-=)* you(~-=)*
// And the replacement look like $1Bye$2 me $3.
// So that we keep the separators at the right place.
foreach ($replacement as $regex => $newstr) {
$regex_array = explode (' ', $regex);
$regex = '(' . $special . '*)' . implode ('(' . $special . '*) ', $regex_array) . '(' . $special . '*)';
$newstr_array = explode (' ', $newstr);
$newstr = "$1";
for ($i = 0; $i < count ($regex_array) - 1; $i++) {
$newstr .= $newstr_array[$i] . '$' . ($i + 2) . ' ';
}
$newstr .= $newstr_array[count($regex_array) - 1] . '$' . (count ($regex_array) + 1);
$clean_text = preg_replace ('#' . $regex . '#isU', $newstr, $clean_text);
}
// Here we re-split one last time.
$clean_text_array = preg_split ('#' . $special . '#', $clean_text, -1, PREG_SPLIT_NO_EMPTY);
// And we merge with $restore.
for ($i = 0, $j = 0; $i < count ($text_array); $i++) {
if (!isset($restore[$i])) {
$restore[$i] = $clean_text_array[$j];
$j++;
}
}
// Now we reorder everything, and make it go back to a string.
ksort ($restore);
$result = implode ($restore);
echo $result;
?>
Will output Bye me ! No, you don't need to run!
[EDIT] Now supporting a custom pattern, which allows to avoid adding useless spaces.
In the following code, I need to remove <div class="grid_8"></div>.
They will always be at the start and finish of my string, for example:
<div class="grid_8"><img src="http://rps.sanscode.com/site/assets/media/images/rps_mini_logo.png" border="0" alt="Rapid Print Solutions" style="margin-bottom: 30px;" />
<h1></h1>
</div>
What is a suitable regex for preg_replace to remove it? 8 can be any number between 1 and 16.
Thanks
Jason
#Amjad...
Here is my code
public function fix_grid(){
$result = db::query("select * from sc_content_components where component_value_1 like '%grid_%'")->fetchAll(PDO::FETCH_ASSOC);
foreach($result as $item){
$json = json_decode($item['component_value_1']);
if(is_null($json)) continue;
$x = reset($json);
echo htmlspecialchars($x);
echo "<p>=======================<b>Changes to: </b></p>";
$patterns = array('/^<(div)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\s]+))?)*)\s*(\/?)>/'
, '/<\/(\div+)[^>]*>$/');
$x = preg_replace($patterns, array('',''), trim($x));
echo htmlspecialchars($x);
echo "<hr>";
$json[0]=$x;
// $ne['component_value_1'] = json_encode($json);
// db::where('component_id', $item['component_id']);
// db::update('sc_content_component', $ne);
}
}
I'm using the regex below (#Amjad Masad) and it doesn't remove the last div.
As you can see I am using trim and it doesn't seem to work
For the stated problem, this is the solution:
Edit: expanded regex =
/^\s*<div\s (?:".*?"|\'.*?\'|[^>]*?)*
(?<=\s)class\s*=\s*(["\'])\s*grid_(?:1[0-6]|[1-9])\s*\1
(?:".*?"|\'.*?\'|[^>]*?)*
>
(.*)
<\/div\s*>
\s*$/xs
replacement = "$2"
For the open
$patterns = array('/^<(div)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>\s]+))?)*)\s*(\/?)>/'
, '/<\/div[^>]*>$/');
preg_replace($patterns, array('','');, trim($htmlString));
Somewhat simpler.
If the 1 to 16 is significant and part of a greater range...
$match = preg_replace("/^<([^>]*)grid_(1[0-6]|[1-9])([^>\d]*)>(.+)<([^>]*)>$/s","$4",trim($str),-1,$hmany);
if($hmany){
echo "$match <br>";
}else{ echo "No match found! <br>"; }
If the 1 to 16 is the only possible range and therefore irrelevant...
$match = preg_replace("/^<([^>]*)>(.+)<([^>]*)>$/s","$2",trim($str),-1,$hmany);
if($hmany){
echo "$match <br>";
}else{ echo "No match found! <br>"; }
Regards.
I am looking for a quick way to replace text in a string that is between two tags.
The string contains <!-- Model # Start --> <!-- Model # End --> Tags.
I just want to replace what is between the tags, I believe preg_replace() will do this but I am not sure how to make it work.
To use preg_replace, pass in the original string and a regular expression - the matching result will be returned. There is not much more to say about that method as you need to understand regular expressions to use it.
Here is a programatic solution, possibly not the most efficient code, but gives you an indication of what it is doing.
$tagOne = "[";
$tagTwo = "]";
$replacement = "Greg";
$text = "Hello, my name is [NAME]";
$startTagPos = strrpos($text, $tagOne);
$endTagPos = strrpos($text, $tagTwo);
$tagLength = $endTagPos - $startTagPos + 1;
$text = substr_replace($text, $replacement, $startTagPos, $tagLength);
echo $text;
Outputs: Hello, my name is Greg.
$tagOne = "[";
$tagTwo = "]";
$replacement = "Greg";
$text = "Hello, my name is [NAME] endie ho [NAME] \n [NAME]";
$textLength = strlen($text);
for ($i; $i< $textLength; $i++) {
$startTagPos = strrpos($text, $tagOne);
$endTagPos = strrpos($text, $tagTwo);
$tagLength = $endTagPos - $startTagPos + 1;
if ($startTagPos<>0) $text = substr_replace($text, $replacement, $startTagPos, $tagLength);
}
echo $text;
Please note, the if statement that checks if there is a tag pos left, otherwise, for all the textlength - # of tags, your start position of 0, in this case 'H', will get gregs :)
The above outputs
Hello, my name is Greg endie ho Greg Greg