Alright so I am using a little bbcode function for a forum I have, working well, so if, in example, I put
[b]Text[/b]
it will print Text in bold.
My issue is, if I have that code:
[b]
Text[/b]
Well it will not work, and just print that as it's right now.
Here is an example of the function I am using:
function BBCode ($string) {
$search = array(
'#\[b\](.*?)\[/b\]#',
);
$replace = array(
'<b>\\1</b>',
);
return preg_replace($search , $replace, $string);
}
Then when echo'ing it:
.nl2br(stripslashes(BBCode($arr_thread_row[main_content]))).
So my question would be, what is necessary so the BBcode works with everything inside it, but no necessarily on the same line.
In example:
[b]
Text
[/b]
Would simply be
Text
Thank you for any help!
Alex
You need the multiline modifier, which makes your pattern something like #\[b\](.*?)\[/b\]#ms
(note the trailing m)
There is actually a pecl extension that parses BBcode, which would be faster and more secure than writing it from scratch yourself.
I use this... It should work.
$bb1 = array(
"/\[url\](.*?)\[\/url\]/is",
"/\[img\](.*?)\[\/img\]/is",
"/\[img\=(.*?)\](.*?)\[\/img\]/is",
"/\[url\=(.*?)\](.*?)\[\/url\]/is",
"/\[red\](.*?)\[\/red\]/is",
"/\[b\](.*?)\[\/b\]/is",
"/\[h(.*?)\](.*?)\[\/h(.*?)\]/is",
"/\[php\](.*?)\[\/php\]/is"
);
$bb2 = array(
'\\1',
'<img alt="" src="\\1"/>',
'<img alt="" class="\\1" src="\\2"/>',
'<a rel="nofollow" target="_blank" href="\\1">\\2</a>',
'<span style="color:#ff0000;">\\1</span>',
'<span style="font-weight:bold;">\\1</span>',
'<h\\1>\\2</h\\3>',
'<pre><code class="php">\\1</code></pre>'
);
$html = preg_replace($bb1, $bb2, $html);
Related
How would I use php preg_replace to parse a string of HTML and replace
alt="20x20" with style="width:20;height:20;"
Any help is appreciated.
I tried this.
$pattern = '/(<img.*) alt="(\d+)x(\d+)"(.*style=")(.*)$/';
$style = '$1$4width:$2px;height:$3px;$5';
$text = preg_replace($pattern, $style, $text);
You don't need preg_replace to do this. You can use str_replace
$html = '<img alt="20x20" />';
preg_match('/<img.*?alt="(.*?)".*>/',$html,$match);
$search = 'alt="' . $match[1] . '"';
list($width, $height) = explode('x', $match[1]);
if(is_numeric($width) && is_numeric($height))
{
$replace = 'style="width:' . $width . 'px;height:' . $height . 'px;"';
echo str_replace($search, $replace, $html);
}
Output:
<img style="width:20px;height:20px;">
If you insist on using regular expressions to alter HTML markup you'll no doubt get stuck sometime, at which point you'd do well to look into something like Python's beautiful soup, or possibly the goode olde tidy library, which I think comes included as part of the PHP spec. But for now:
<?php
$originalString = 'Your string containing <img src="xyz.png" alt="20x20">';
$patternToFind = '/alt="20x20"/i';
$replacementString = 'style="width:20;height:20;"';
preg_replace($patternToFind, $replacementString, $originalString);
?>
And since it seems a lot of people are mighty peeved at what seems to be a code request, you might check this link out for php.net's guidance. It's not always this clear in explaining PHP's constructs, but would have solved your problem easily in this case:
http://php.net/manual/en/function.preg-replace.php
As mentioned in the comments you should use DOM to manipulate HTML codes.
If you want to do this by preg_replace anyway, I'd suggest to find out the regex by yourself with the help of sites like this one.
I've small preg_replace problem. I need to resize iframe code output so I'm using preg_replace, regex seems to work fine, but result is same as input no changes. Here code I'm using:
$video_code = preg_replace( '/width="(.*?)"/', 'width="'.$width.'"', $video_code );
$video_code = preg_replace( '/height="(.*?)"/', 'height="'.$height.'"', $video_code );
This iframe that $video_code contains:
<iframe class='sproutvideo-player' type='text/html' src='http://videos.sproutvideo.com/embed/189bd8b4191ee1c390/d0dc5859e1d409ed?type=hd®ularColors0=666565®ularColors1=595756&hoverColors0=ed2409&hoverColors1=d1390f&highlightColors1=c9c3c9&noBigPlay=true' width='768' height='432' frameborder='0'></iframe>
Any idea why is this happening?
Thanks
George
Try this:
$video_code = preg_replace ('/(width=[\'"])(.*?)([\'"])/', '$1620$3', $video_code);
$video_code = preg_replace ('/(height=[\'"])(.*?)([\'"])/', '$1' . $height . '$3', $video_code);
Escaped some characters and you're replacing everything inbetween the (), so the text height= in the replacement pattern is unnecessary.
I used your code and it worked fine for me. (made a few small changes, but not much)
Here is the code i used:
http://codepad.viper-7.com/fafGYW
Hope this helps.
$video_code = preg_replace('/width=[\'"][^\'"]+[\'"]/', 'width="'.$width.'"', $video_code);
$video_code = preg_replace('/height=[\'"][^\'"]+[\'"]/', 'height="'.$height.'"', $video_code);
How can i strip html tag except the content inside the pre tag
code
$content="
<div id="wrapper">
Notes
</div>
<pre>
<div id="loginfos">asdasd</div>
</pre>
";
While using strip_tags($content,'') the html inside the pre tag too stripped of. but i don't want the html inside pre stripped off
Try :
echo strip_tags($text, '<pre>');
You may do the following:
Use preg_replace with 'e' modifier to replace contents of pre tags with some strings like ###1###, ###2###, etc. while storing this contents in some array
Run strip_tags()
Run preg_relace with 'e' modifier again to restore ###1###, etc. into original contents.
A bit kludgy but should work.
<?php
$document=html_entity_decode($content);
$search = array ("'<script[^>]*?>.*?</script>'si","'<[/!]*?[^<>]*?>'si","'([rn])[s]+'","'&(quot|#34);'i","'&(amp|#38);'i","'&(lt|#60);'i","'&(gt|#62);'i","'&(nbsp|#160);'i","'&(iexcl|#161);'i","'&(cent|#162);'i","'&(pound|#163);'i","'&(copy|#169);'i","'&#(d+);'e");
$replace = array ("","","\1","\"","&","<",">"," ",chr(161),chr(162),chr(163),chr(169),"chr(\1)");
$text = preg_replace($search, $replace, $document);
echo $text;
?>
$text = 'YOUR CODE HERE';
$org_text = $text;
// hide content within pre tags
$text = preg_replace( '/(<pre[^>]*>)(.*?)(<\/pre>)/is', '$1###pre###$3', $text );
// filter content
$text = strip_tags( $text, '<pre>' );
// insert back content of pre tags
if ( preg_match_all( '/(<pre[^>]*>)(.*?)(<\/pre>)/is', $org_text, $parts ) ) {
foreach ( $parts[2] as $code ) {
$text = preg_replace( '/###pre###/', $code, $text, 1 );
}
}
print_r( $text );
Ok!, you leave nothing but one choice: Regular Expressions... Nobody likes 'em, but they sure get the job done. First, replace the problematic text with something weird, like this:
preg_replace("#<pre>(.+?)</pre>#", "||k||", $content);
This will effectively change your
<pre> blah, blah, bllah....</pre>
for something else, and then call
strip_tags($content);
After that, you can just replace the original value in ||k||(or whatever you choose) and you'll get the desired result.
I think your content is not stored very well in the $content variable
could you check once by converting inner double quotes to single quotes
$content="
<div id='wrapper'>
Notes
</div>
<pre>
<div id='loginfos'>asdasd</div>
</pre>
";
strip_tags($content, '<pre>');
You may do the following:
Use preg_replace with 'e' modifier to replace contents of pre tags with some strings like ###1###, ###2###, etc. while storing this contents in some array
Run strip_tags()
Run preg_relace with 'e' modifier again to restore ###1###, etc. into original contents.
A bit kludgy but should work.
Could you please write full code. I understood, but something goes wrong. Please write full programming code
i have got a simple problem :( I need to replace text smilies with the according smiley-image. ok.. thats not really complex, but now i have to replace only smilie appereances outside of HTML Tags. short examplae:
Text:
Thats a good example :/ .. with a link inside.
i want to replace ":/" with the image of this smiley...
ok, how to do that the best way?
I won't try to create some super script but think about it.... smilies are just about always surrounded by spaces. So str replace ' :/ ' with the smiley. You could be saying "what about a smiley at the end of a sentence(where it would be used the most)". Well just check for at least one space on either the left or the right of a potential smiley.
Using the above scripts:
$smiley_array = array(
":) " => "<a href...>",
" :)" => "<a href...>",
":/ " => "<a href...>",
" :/" => "<a href...>");
$codes = array_keys($smiley_array);
$links = array_values($smiley_array);
$str = str_replace($codes, $links, $str);
If you rather not have to type everything twice you can generate the array from a single smiley array.
Why don't you just try to use some special chars around your smiley text like this maybe -:/-
This will make your smiley text some kind of unique and easy to recognize
Use preg_replace with a lookbehind assertion. Example:
$smileys = array(
':/' => '<img src="..." alt=":/">'
);
foreach ($smileys as $smile => $img) {
$text = preg_replace('#(?<!<[^<>]*)' . preg_quote($smile, '#') . '#',
$img, $text);
}
The regex should match only smileys that are not inside angle brackets. This might be slow if you have a lot of false positives.
I wouldn't know about the best way, only the way I would do it.
Build an array having the smiley codes as the keys and the link as the value. The use str_replace. Pass as "needle" an array of the keys (the smiley codes) and as "replace" an array of the values.
For instance, suppose you have something like this:
$smiley_array = array(":)" => "<a href...>",
":(" => "<a href=....>");
$codes = array_keys($smiley_array);
$links = array_values($smiley_array);
$str = str_replace($codes, $links, $str);
EDIT: In case this could accidentally replace other instances with smiley-links you should consider using regexes with preg_replace. Obviously preg_replace is slower than str_replace.
You can use regex, or the extra sloppy version of the above:
$smiley_array = array(":)" => "<a href...>",
":(" => "<a href=....>");
$codes = array_keys($smiley_array);
$links = array_values($smiley_array);
$str = str_replace("://", "%%QF%%", $str);
$str = str_replace($codes, $links, $str);
$str = str_replace("%%QF%%", "://", $str);
Actually, assuming str_replace follows the array sorting...
this should work:
$smiley_array = array("://" => "%%QF%%", ":)" => "<a href...>",
":(" => "<a href=....>", "%%QF%%" => "://");
$codes = array_keys($smiley_array);
$links = array_values($smiley_array);
$str = str_replace($codes, $links, $str);
Possible overkill (increased cpu/load), but 99.99999999% safe:
<?php
$n = new DOMDocument();
$n->loadHTML('<p>Thats a good example :/ .. with a link inside.</p>');
$x = new DOMXPath($n);
$instances = $x->query('//text()[contains(.,\':/\')]');//or use '//*[child::text()]' for all textnodes
foreach($instances as $node){
if($node instanceof DOMText && preg_match_all('/:\//',$node->wholeText,$matches,PREG_OFFSET_CAPTURE|PREG_SET_ORDER)){
foreach($matches[0] as $match){
$newnode = $node->splitText($match[1]);
$newnode->replaceData(0,strlen($match[0]),'');
$img = $n->createElement('img');
$img->setAttribute('src','smily.gif');
$img = $newnode->parentNode->insertBefore($img,$newnode);
//var_dump($match);
}
}
}
var_dump($n->saveHTML());
?>
But in reality you do not want to do this all that often, save once, show many, if you are letting users edit the html (beit in wysiwyg or elsewise, the 'return' transformation (img to text) is a whole lot lighter. Up to you to expand with different smilies (one monster regex to match them, or several smaller ones / strstr()'s for readability, and a array for smiley to src (e.g. array(':/'=>'frown.gif')) would be the way to go.
I want to replace the class with the div text like this :
This: <div class="grid-flags" >FOO</div>
Becomes: <div class="iconFoo" ></div>
So the class is changed to "icon". ucfirst(strtolower(FOO)) and the text is removed
Test HTML
<div class="grid-flags" >FOO</div>
Pattern
'/class=\"grid-flags\" \>(FOO|BAR|BAZ)/e'
Replacement
'class="icon'.ucfirst(strtolower($1).'"'
This is one example of a replacement string I've tried out of seemingly hundreds. I read that the /e modifier evaluates the PHP code but I don't understand how it works in my case because I need the double quotes around the class name so I'm lost as to which way to do this.
I tried variations on the backref eg. strtolower('$1'), strtolower('\1'), strtolower('{$1}')
I've tried single and double quotes and various escaping etc and nothing has worked yet.
I even tried preg_replace_callback() with no luck
function callback($matches){
return 'class="icon"'.ucfirst(strtolower($matches[0])).'"';
}
It was difficult for me to try to work out what you meant, but I think you want something like this:
preg_replace('/class="grid-flags" \>(FOO|BAR|BAZ)/e',
'\'class="icon\'.ucfirst(strtolower("$1")).\'">\'',
$text);
Output for your example input:
<div class="iconFoo"></div>
If this isn't what you want, could you please give us some example inputs and outputs?
And I have to agree that this would be easier with an HTML parser.
Instead of using the e(valuate) option you can use preg_replace_callback().
$text = '<div class="grid-flags" >FOO</div>';
$pattern = '/class="grid-flags" >(FOO|BAR|BAZ)/';
$myCB = function($cap) {
return 'class="icon'.ucfirst($cap[1]).'" >';
};
echo preg_replace_callback($pattern, $myCB, $text);
But instead of using regular expressions you might want to consider a more suitable parser for html like simple_html_dom or php's DOM extension.
This works for me
$html = '<div class="grid-flags" >FOO</div>';
echo preg_replace_callback(
'/class *= *\"grid-flags\" *\>(FOO|BAR|BAZ)/'
, create_function( '$matches', 'return \'class="icon\' . ucfirst(strtolower($matches[1])) .\'">\'.$matches[1];' )
, $html
);
Just be aware of the problems of parsing HTML with regex.