I have problem with preg_replace, I need it to replace <td class="td_supltrid_3" width="11%"><p> 4A8</p> with only 4A8. When I use this pattern:
'/\<td class\=\"td_supltrid_3\" width\=\"11%\"\>\<p\> ...\<\/p\>/'
it doesn't find it. However, when I use preg_match, it finds searched expression without problem. Can you tell me there is the problem? Whole code:
preg_replace('/\<td class\=\"td_supltrid_3\" width\=\"11%\"\>\<p\> (...)\<\/p\>/', '$1', $str)
You need to change (...) to (.*?), which will grab everything up to the trailing </p>
<?php echo preg_replace('/<td class\=\"td_supltrid_3\" width\=\"11%\"><p>(.*?)<\/p>/', '$1', '<td class="td_supltrid_3" width="11%"><p> 4A8</p>'); ?>
Related
I'm trying to use a regex to find and replace all URLs in a forum system. This works but it also selects anything that is within bbcode. This shouldn't be happening.
My code is as follows:
<?php
function make_links_clickable($text){
return preg_replace('!(([^=](f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9#:%_+.~#?&;//=]+)!i', '$1', $text);
}
//$text = "https://www.mcgamerzone.com<br>http://www.mcgamerzone.com/help/support<br>Just text<br>http://www.google.com/<br><b>More text</b>";
$text = "#Theareak We know this and [b][url=https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks]here[/url] [/b]is an explanation, we are trying to fix this asap! https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks aaa";
echo "<b>Unparsed text:</b><br>";
echo $text;
echo "<br><br>";
echo "<b>Parsed text:</b><br>";
echo make_links_clickable($text);
?>
All urls that occur in bb-code are following up on a = character, meaning that I don't want anything that starts with = to be selected.
I basically have that working but this results in selecting 1 extra character in in front of the string that should be selected.
I'm not very familiar with regex. The final output of my code is this:
<b>Unparsed text:</b><br>
#Theareak We know this and [b][url=https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks]here[/url] [/b]is an explanation, we are trying to fix this asap! https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks aaa<br>
<br>
<b>Parsed text:</b><br>
#Theareak We know this and [b][url=https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks]here[/url] [/b]is an explanation, we are trying to fix this asap! https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks aaa
You can match and skip [url=...] like this:
\[url=[^\]]*](*SKIP)(?!)|(((f|ht)tps?://)[-a-zA-Zа-яёЁА-Я()0-9#:%_+.\~#?&;/=]+)
See regex demo
That way, you will only match the URLs outside the [url=...] tag.
IDEONE demo:
function make_links_clickable($text){
return preg_replace('~\[url=[^\]]*](*SKIP)(?!)|(((f|ht)tps?://)[-a-zA-Zа-яёЁА-Я()0-9#:%_+.\~#?&;/=]+)~iu', '$1', $text);
}
$text = "#Theareak We know this and [b][url=https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks]here[/url] [/b]is an explanation, we are trying to fix this asap! https://www.mcgamerzone.com/news/67/False-positive-proxy-bans-and-bot-attacks aaa";
echo "<b>Parsed text:</b><br>";
echo make_links_clickable($text);
You can use a negative lookbehind (?<!=) instead of your negated class. It asserts that what is going to be matched isn't preceded by something.
Example
i got this table generated with php:
a function generates a string with all the html code:
<table><tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr><tr><td>2</td><td>4</td><td>6</td><td>8</td><td>10</td><td>12</td><td>14</td><td>16</td><td>18</td><td>20</td></tr><tr><td>3</td><td>6</td><td>9</td><td>12</td><td>15</td><td>18</td><td>21</td><td>24</td><td>27</td><td>30</td></tr><tr><td>4</td><td>8</td><td>12</td><td>16</td> .... </table>
now i want to make the numbers 1 to 10 black. i'm trying to replace '<td>(10|[0-9])</td>' with <td style="font-weight: bold">THE-ORIGINAL-NUMBER</td>.
Thanx in advance!
p.s. i know there're alot of similir answers out there but i just couldnt figure it out.. is there an actually noob-friendly tut/glossary of regex out there? i couldn't really find a modern day site.
If you are matching this regular expression:
<td>(10|[0-9])</td>
You are capturing 10|[0-9] into capture group #1. This can be referenced in your replacement with either of the following backreferences:
\1
$1
Full PHP code:
$html = '<td>1</td>';
$html = preg_replace(
'~<td>(10|[0-9])</td>~',
'<td style="font-weight: bold">\1</td>',
$html
);
use this regex
(?<=<td>)(10|[0-9])(?=<\/td>)
replace group #1 with:
<span class="BoldText">$1</span>
Style:
.BoldText {
font-weight: bold;
}
using <b> may be useful:
replace
'~<td>(10|[0-9])</td>~'
with
'<td><b>\1</b></td>'
I want to change
<lang class='brush:xhtml'>test</lang>
to
<pre class='brush:xhtml'>test</pre>
my code like that.
<?php
$content="<lang class='brush:xhtml'>test</lang>";
$pattern=array();
$replace=array();
$pattern[0]="/<lang class=([A-Za-z='\":])* </";
$replace[0]="<pre $1>";
$pattern[1]="/<lang>/";
$replace[1]="</pre>";
echo preg_replace($pattern, $replace,$content);
?>
but it's not working. How to change my code or something wrong in my code ?
There's quite a few problems:
Pattern 0 has the * outside the group, so the group only matches one character
Pattern 0 doesn't include the class= in the group, and the replacement doesn't have it either, so there won't be a class= in the replaced string
Pattern 0 has a space after the class, but there isn't one in the content string
Pattern 1 looks for lang instead of /lang
This will work:
$pattern[0]="/<lang (class=[A-Za-z='\":]*) ?>/";
$replace[0]="<pre $1>";
$pattern[1]="/<\/lang>/";
$replace[1]="</pre>";
How bout without regex? :)
<?php
$content="<lang class='brush:xhtml'>test</lang>";
$content = html_entity_decode($content);
$content = str_replace('lang','pre',$content);
echo $content;
?>
Using preg_replace is a lot faster than str_replace.
$str = preg_replace("/<lang class=([A-Za-z'\":]+)>(.*?)<\/lang>/", "<pre class=$1>$2</pre>", $str);
Execution time: 0.039815s
[preg_replace]
Time: 0.009518s (23.9%)
[str_replace]
Time: 0.030297s (76.1%)
Test Comparison:
[preg_replace]
compared with.........str_replace 218.31% faster
So preg_replace is 218.31% faster than the str_replace method mentioned above. Each tested 1000 times.
I have a variable $link_item, it's used with echo and gives the strings like
<span class="name">Google</span>http://google.com
How to remove "<span class="name">Google</span>" from string?
It should give just "http://google.com".
Heard it can be done with regex(), please help.
Without regex:
echo substr($link_item, stripos($link_item, 'http:'))
But this only works if the first part (i.e. <span class="name">Google</span>) never contains http:. If you can assure this: here you go :)
Reference: substr, stripos
Update:
As #Gordon points out in his comment, my code is doing the same as strstr() already does. I just put it here in case one does not read the comments:
echo strstr($link_item, 'http://');
$string = '<span class="name">Google</span>http://google.com';
$pieces = explode("</span>",$string);
//In case there is more than one span before the URL
echo $pieces[count($pieces) -1];
Solved:
$contents = '<span class="name">Google</span>http://google.com';
$new_text = preg_replace('/<span[^>]*>([\s\S]*?)<\/span[^>]*>/', '', $contents);
echo $new_text;
// outputs -> http://google.com
Don't use a regex. Use a HTML parser to extract only the text you want from it.
Made myself
$link_item_url = preg_replace('#<span[^>]*?>.*?</span>#si', '', $link_item);
This will remove any <span + something + </span> from variable $link_item.
Thanks for all.
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.