Preg replace if words are not inside an header - php

I'm trying to do something simple but i'm failing :
I want to use preg_replace in PHP to make keywords become a link, but i don't want to insert it in headings.
My actual preg_replace :
$data_replace = '$1';
$word_to_replace = "keyword";
$data_source = "<h1>keyword</h1><p>keyword</p>"
$pattern = "/\\b(?!<h[0-6]*\>)(.*?)(" . trim($word_to_replace) . ")(.*?)(?!<\/h[0-6]>)\\b/";
preg_replace($pattern, $data_replace, $data_source, 1);
And I want to get :
<h1>keyword</h1><p>keyword</p>
For now, my output gives :
<h1>keyword</h1><p>keyword</p>
Where am i wrong in my regex pattern ?
Thanks !

Try this:
<?php
$data_replace = '$1';
$words = ["keyword","foo"];
$out = "<h1>keyword</h1><p>keyword</p>";
foreach ($words as $word){
$pattern = "/(<[^h].*?>)($word)(<\/)/";
$out = preg_replace($pattern, "\\1$word\\3", $out);
}
var_dump($out);
Produces:
dejavu:~ jancha$ php -q aa.php
string(46) "<h1>keyword</h1><p>keyword</p>"
p.s.
this has enhancement for multiple keywords.

Related

PHP preg_replace all text changing

I want to make some changes to the html but I have to follow certain rules.
I have a source code like this;
A beautiful sentence http://www.google.com/test, You can reach here http://www.google.com/test-mi or http://www.google.com/test/aliveli
I need to convert this into the following;
A beautiful sentence http://test.google.com/, You can reach here http://www.google.com/test-mi or http://test.google.com/aliveli
I tried using str_replace;
$html = str_replace('://www.google.com/test','://test.google.com');
When I use it like this, I get an incorrect result like;
A beautiful sentence http://test.google.com/, You can reach here http://test.google.com/-mi or http://test.google.com/aliveli
Wrong replace: http://test.google.com/-mi
How can I do this with preg_replace?
With regex you can use a word boundary and a lookahead to prevent replacing at -
$pattern = '~://www\.google\.com/test\b(?!-)~';
$html = preg_replace($pattern, "://test.google.com", $html);
Here is a regex demo at regex101 and a php demo at eval.in
Be aware, that you need to escape certain characters by a backslash from it's special meaning to match them literally when using regex.
It seems you're replacing the subdirectory test to subdomain. Your case seems to be too complicated. But I've given my best to apply some logic which may be reliable or may not be unless your string stays with the same structure. But you can give a try with this code:
$html = "A beautiful sentence http://www.google.com/test, You can reach here http://www.google.com/test-mi or http://www.google.com/test/aliveli";
function set_subdomain_string($html, $subdomain_word) {
$html = explode(' ', $html);
foreach($html as &$value) {
$parse_html = parse_url($value);
if(count($parse_html) > 1) {
$path = preg_replace('/[^0-9a-zA-Z\/-_]/', '', $parse_html['path']);
preg_match('/[^0-9a-zA-Z\/-_]/', $parse_html['path'], $match);
if(preg_match_all('/(test$|test\/)/', $path)) {
$path = preg_replace('/(test$|test\/)/', '', $path);
$host = preg_replace('/www/', 'test', $parse_html['host']);
$parse_html['host'] = $host;
if(!empty($match)) {
$parse_html['path'] = $path . $match[0];
} else {
$parse_html['path'] = $path;
}
unset($parse_html['scheme']);
$url_string = "http://" . implode('', $parse_html);
$value = $url_string;
}
}
unset($value);
}
$html = implode(' ', $html);
return $html;
}
echo "<p>{$html}</p>";
$modified_html = set_subdomain_string($html, 'test');
echo "<p>{$modified_html}</p>";
Hope it helps.
If the sentence is the only case in your problem you don't need to start struggling with preg_replace.
Just change your str_replace() functioin call to the following(with the ',' at the end of search string section):
$html = str_replace('://www.google.com/test,','://test.google.com/,');
This matches the first occurance of desired search parameter, and for the last one in your target sentence, add this(Note the '/' at the end):
$html = str_replace('://www.google.com/test/','://test.google.com/');
update:
Use these two:
$targetStr = preg_replace("/:\/\/www.google.com\/test[\s\/]/", "://test.google.com/", $targetStr);
It will match against all but the ones with comma at the end. For those, use you sould use the following:
$targetStr = preg_replace("/:\/\/www.google.com\/test,/", "://test.google.com/,", $targetStr);

PHP function that convert 'a,b' to ' "a","b" ' [duplicate]

This question already has answers here:
Add quotation marks to comma delimited string in PHP
(5 answers)
Closed 1 year ago.
I have a variable with string value of 'laptop,Bag' and I want it to look like ' "laptop","Bag" 'or "laptop","Bag". How could I do this one? Is there any php function that could get this job done? Any help please.
This would work. It first, explodes the string into an array. And then implodes it with speech marks & finishes up by adding the opening & closing speech mark.
$string = "laptop,bag";
$explode = explode(",", $string);
$implode = '"'.implode('","', $explode).'"';
echo $implode;
Output:
"laptop","bag"
That's what str_replace is for:
$result = '"'.str_replace(',', '","', $str).'"';
This would be very easy to do.
$string = 'laptop,bag';
$items = explode(',', $string);
$newString = '"'.implode('","', $items).'"';
That should turn 'laptop,bag' into "laptop","bag".
Wrapping that in a function would be as simple as this:
function changeString($string) {
$items = explode(',', $string);
$newString = '"'.implode('","', $items).'"';
return $newString;
}
I think you can explode your string as array and loop throw it creating your new string
function create_string($string)
{
$string_array = explode(",", $string);
$new_string = '';
foreach($string_array as $str)
{
$new_string .= '"'.$str.'",';
}
$new_string = substr($new_string,-1);
return $new_string;
}
Now you simply pass your string the function
$string = 'laptop,Bag';
echo create_string($string);
//output "laptop","Bag"
For your specific example, this code would do the trick:
<?php
$string = 'laptop,bag';
$new_string = ' "' . str_replace(',', '","', $string) . '" ';
// $new_string: "laptop","bag"
?>
That code would also work if you had more items in that list, as long as they are comma-separated.
Use preg_replace():
$input_lines="laptop,bag";
echo preg_replace("/(\w+)/", '"$1"', $input_lines);
Output:
'"laptop","Bag"'
I think you can perform that using explode in php converting that string in to an array.
$tags = "laptop,bag";
$tagsArray = explode(",", $tags);
echo $tagsArray[0]; // laptop
echo $tagsArray[1]; // bag
Reference
http://us2.php.net/manual/en/function.explode.php
related post take a look maybe could solve your problem.
How can I split a comma delimited string into an array in PHP?

perl match transition to php preg_match

I have this piece of programming written in perl:
$string = '[jkl][mno][ghi]';
$search = 'John';
if ($search =~ /$string/i) {
do....
How do I translate that into php ?
I tried with preg_match but obviously it has a different syntax. Basically , the if statement above will search if any of the letters located in between [] brackets match $search ..
How can I do this in php while keeping the same $string / $search values ?
Update - php code
<?php
$string = "dan" ;
$search = "[def][abc][mno";
if (preg_match("/".$search."/i",$string)) {
echo "found it";
}
?>
You should've tried/read first.
$string = '[jkl][mno][ghi]';
$search = 'John';
if (preg_match('/' . $string . '/i', $search)) {
do....
Regexp syntax should be the same if you use preg_match. The difference is how you specify options. The can look like this:
$string = '[jkl][mno][ghi]';
$search = 'John';
if (preg_match("/$string/i", $search)) {
do....
Update
In your PHP code looks like you're missing ending ] in $search = "[def][abc][mno";. Should probably look like:
$string = "dan" ;
$search = "[def][abc][mno]";
if (preg_match("/".$search."/i",$string)) {
echo "found it";
}

Link each word of string WITHOUT linking <br>

I'm using a PHP script to link each word of the string:
<?
$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
echo ''.$value.'';
}
?>
How do I link each word of the string $str without linking the <br>s?
You can just use preg_replace
// More complext string
$str = "hello<br> guys good man Google <br /> hurry";
// Url Template
$template = '%1$s';
// Replace Words
echo preg_replace("/(?!(?:[^<]+>|[^>]+<\/a>))\b([a-z]+)\b/is", sprintf($template, "\\1"), $str);
Output
hello
<br>
guys
good
man
Google
<br />
hurry
Use the strip_tags() function before/in your explode:
$arr = explode (' ', strip_tags($str));
Untested, but start with JvO's code and put the links back into the original string:
$str = "hello<br> guys good man";
$arr = explode (' ', strip_tags($str));
foreach($arr as $value) {
$link = ''.$value.'';
$str = str_replace($value, $link, $str);
}
echo $str;
Note that you can save time by removing duplicates from $arr.
Edit: in fact, you must remove duplicates from $arr, or things will get ugly:
$arr = array_unique(explode (' ', strip_tags($str)));
... and another edit to the original code for an error.
Before you form the link, process the string first:
$proc_val = preg_replace('/<br>/', '', $value);
echo ''.$value.'';
Not sure what you were saying in the comment of Jvo's answer, but you can always use the striptags in the foreach as well and only strip the link part.
foreach($arr as $value){
echo ''.$value.'';
}
So here is the full code:
<?
$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
echo ''.$value.'';
}
?>
You really should think about what explode(' ', $str) is going to do though.
Any time any HTML tag has attributes to it like <span style="color: red;"> you are going to run into trouble. You should strip_tags first, on the entire string, then process it. Keep an HTML version as a separate string if you need to add stuff later.
Why not just explode the string as you currently are and simply strip the tags in the URL.
$str = "hello<br> guys good man";
$arr = explode(' ', $str);
foreach($arr as $value){
echo ''.$value.'';
}
This will output the following HTML which is what I believe you want.
hello<br>
guys
good
man
If the string is quite long, and can contain any number of tags, including <p>, <h1> and <br> as well as the more correct <br/>, you could consider parsing the lot, and use str_replace:
$string = 'Foo<br/>Hello Bar!';
$DOM = new DOMDocument;
//make sure all breaks are preceded by a space, if not words might be concatenated by accident
$DOM->loadHTML(str_replace('<br', ' <br', $string));
//get all nodes
$nodes = $DOM->getElementsByTagName('*');
//get the text, split it and replace, but keep track of replaced words
$replaced = array();
for ($i = 0, $j = $nodes->length; $i<$j;$i++)
{
$words = explode(' ',$nodes->item($i)->nodeValue);
while($word = array_shift($words))
{
if (!array_key_exists($word, $replaced))
{//avoid replacing twice (and thus creating a link within a link)
$replaced[$word] = true;
$string = str_replace($word, ''.$word.'', $string);
}
}
}
This code is tested and working.

Parsing a Source With REGEX

I want to get all Performance ID's from this page .
<?php
$content = file_get_contents("http://www124.popmundo.com/Common/Performances.asp?action=ComingPerformances&ArtistID=1962457");
$regex = "Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)";
//$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/";
//$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/s";
//all pattern variations tested, not working
if(preg_match_all($regex, $content, $m))
print_r($m);
else
echo "FALSE";
// this is returning FALSE
Use & instead of & in your regex.
Try this:
$regex = "/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/";
It looks like an escape problem. Not knowing php, I would guess one of these
might fix it:
$regex = 'Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)';
or
$regex = "Performances\\.asp\\?action=Arrangements&PerformanceID=([0-9]+)";
or
$regex = '/Performances\.asp\?action=Arrangements&PerformanceID=([0-9]+)/';

Categories