How to use preg_replace with url encoded $_GET? - php

I have a an url which looks like this https://URL.DOMAIN/blog.php?id=43&q=echo%20%27test%27.
When I use <?php echo $_GET['q'] ?> it displays echo 'test' which is what I want.
I am using this variable inside a preg_replace function which is basically made to apply a yellow background under matched strings:
preg_replace('/\b('.$_GET['q'].')\b/iu', '<span class="research-news-found">$1</span>', $news_content);
It works perfectly for "normal" strings like "apple" or whatever, but when there is a ' inside the search query it doesn't match anything.
Code example
$news_content = $news_display['news_description'];
if(isset($_GET['q'])){
$news_content = preg_replace('/\b('.$_GET['q'].')\b/iu', '<span class="research-news-found">$1</span>', $news_content);
}
$news_display['news_description'] contains the text output from DB.

Just make the pattern greedy ? and remove the trailing word boundary \b since ' is not a word character and is a word boundary:
$news_content = preg_replace('/\b('.$_GET['q'].'?)/iu',
'<span class="research-news-found">$1</span>',
$news_content);
Demo
But if you are hoping that it will actually echo test, then no. You would need to restructure your question to state what you want to achieve, not how to get this replacement to work.

Related

how to do echo from a string, only from values that are between a specific stretch[href tag] of the string?

[PHP]I have a variable for storing strings (a BIIGGG page source code as string), I want to echo only interesting strings (that I need to extract to use in a project, dozens of them), and they are inside the quotation marks of the tag
but I just want to capture the values that start with the letter: N (news)
[<a href="/news7044449/exclusive_news_sunday_"]
<a href="/n[ews7044449/exclusive_news_sunday_]"
that is, I think you will have to work with match using: [a href="/n]
how to do that to define that the echo will delete all the texts of the variable, showing only:
note that there are other hrefs tags with values that start with other letters, such as the letter 'P' : href="/profiles... (This does not interest me.)
$string = '</div><span class="news-hd-mark">HD</span></div><p>exclusive_news_sunday_</p><p class="metadata"><span class="bg">Czech AV<span class="mobile-hide"> - 5.4M Views</span>
- <span class="duration">7 min</span></span></p></div><script>xv.thumbs.preparenews(7044449);</script>
<div id="news_31720715" class="thumb-block "><div class="thumb-inside"><div class="thumb"><a href="/news31720715/my_sister_running_every_single_morning"><img src="https://static-hw.xnewss.com/img/lightbox/lightbox-blank.gif"';
I imagine something like this:
$removes_everything_except_values_from_the_href_tag_starting_with_the_letter_n = ('/something regex expresion I think /' or preg_match, substring?);
echo $string = str_replace($removes_everything_except_values_from_the_href_tag_starting_with_the_letter_n,'',$string);
expected output: /news7044449/exclusive_news_sunday_
NOTE: it is not essential to be through a variable, it can be from a .txt file the place where the extracts will be extracted, and not necessarily a variable.
thanks.
I believe this will help her.
<?php
$source = file_get_contents("code.html");
preg_match_all("/<a href=\"(\/n(?:.+?))\"[^>]*>/", $source, $results);
var_export( end($results) );
Step by Step Regex:
Regex Demo
Regex Debugger
To get just the links out of the $results array from Valdeir's answer:
foreach ($results as $r) {
echo $r;
// alt: to display them with an HTML break tag after each one
echo $r."<br>\n";
}

Regex to select url except when = is directly infront of it

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

PHP replace : find and replace the same characters with different text

How can I find and replace the same characters in a string with two different characters? I.E. The first occurrence with one character, and the second one with another character, for the entire string in one go?
This is what I'm trying to do (so users need not type html in the body): I've used preg_replace here, but I'll willing to use anything else.
$str = $str = '>>Hello, this is code>> Here is some text >>This is more code>>';
$str = preg_replace('#[>>]+#','[code]',$str);
echo $str;
//output from the above
//[code]Hello, this is code[code] Here is some text [code]This is more code[code]
//expected output
//[code]Hello, this is code[/code] Here is some text [code]This is more code[/code]
But problem here is, both >> get replaced with [code]. Is it possible to somehow replace the first >> with [code] and the second >> with a [/code] for the entire output?
Does php have something to do this in one go? How can this be done?
$str = '>>Hello, this is code>> Here is some text >>This is more code>>';
echo preg_replace( "#>>([^>]+)>>#", "[code]$1[/code]", $str );
The above will fail if something like the following is your input:
>>Here is code >to break >stuff>>
To deal with this, use negative lookahead:
#>>((?!>[^>]).+?)>>#
will be your pattern.
echo preg_replace( "#>>((?!>[^>]).+?)>>#", "[code]$1[/code]", $str );

Struggling to use a regex function to find a link in a string

I am trying to extract a string from another string using php.
At the moment im using:
<?php
$testVal = $node->field_link[0]['view'];
$testVal = preg_replace("#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie", "'$3$4'", $testVal);
print "testVal = ";
print $testVal;
?>
This seems to be printing my entire string at the moment.
Now what i want to do is: extract a web address if there is one and save it as a variable called testVal.
I am a novice so please explain what i am doing wrong. Also i have looked at other questions and have used the regex from one.
For #bos
Input:
<iframe width="560" height="315" src="http://www.youtube.com/embed/CLXt3yh2g0s" frameborder="0" allowfullscreen></iframe>
Desired Output
http://www.youtube.com/embed/CLXt3yh2g0s
Well, you say you want to populate $testVal with the extracted web address, but you're using preg_replace instead of preg_match. You use preg_replace when you wish to replace occurrences, and you use preg_match (or preg_match_all) when you want to find occurrences.
If you want to replace URLs with links (<a> tags) like in your example, use something like this:
<?php
$testVal = preg_replace(
'/((?:https?:\/\/|ftp:\/\/|irc:\/\/)[^\s<>()"]+?(?:\([^\s<>()"]*?\)[^\s<>()"]*?)*)((?:\s|<|>|"|\.||\]|!|\?|,|,|")*(?:[\s<>()"]|$))/',
'<a target="_blank" rel="nofollow" href="$1">$1</a>$2',
$testVal
);
If you want to instead simply locate a URL from a string, try (using your regex now instead of mine above):
<?php
$testVal = $node->field_link[0]['view'];
if(!preg_match("#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie", $testVal, $matches)) {
echo "Not found!";
else {
echo "URL: " . $matches[1];
}
When you use preg_match, the (optional) third parameter is filled with the results of the search. $matches[0] would contain the string that matched the entire pattern, $matches[1] would contain the first capture group, $matches[2] the second, and so on.

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.

Categories