I want write a simple code that convert special words to special link (for wiki plugin), if it's not a link!
For example suppose we have a text "Hello! How are you?!" and
we want convert are to are, but if we have Hello! How are you?! or Hello! How are you?! does not change. Because it's a link.
How can I do it in PHP?! With preg_replace?! How to?
Thanks.
It's easy.
<?php
$string = "Hello! How are you?!";
$stringTwo = "Hello! how are you?!";
function turnTheWordIntoALink($string, $word, $link) {
if(isLink($string)) {
return $string;
} else {
$string = str_replace($word, "" . $word . "", $string);
return $string;
}
}
function isLink($string) {
return preg_match("/(<a href=\".\">)/", $string);
}
echo turnTheWordIntoALink($string, 'are', 'http://google.com');
echo turnTheWordIntoALink($stringTwo, 'are', 'http://google.com');
Output:
First function output: Hello! How are you?!
Second function output: Hello! how are you?!
Alternative:
If you want to not detect <a> tags which were closed, you can use this alternative code:
$stringThree = "Hello! how <a href=\"#\">are you?!";
function turnTheWordIntoALink($string, $word, $link) {
if(isLink($string)) {
return $string;
} else {
$string = str_replace($word, "" . $word . "", $string);
return $string;
}
}
function isLink($string) {
return preg_match("/(<a href=\".\">)+(.)+(<\/a>)/", $string);
}
echo turnTheWordIntoALink($stringThree, 'are', 'http://google.com') . "\n";
This gives the output: Hello! how <a href="http://google.com">are you?!
this code is about : if there is a some URL in some phrase it will convert to a link
$word = 'hello how are you google.com, wish you good time';
$prg = "/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
if(preg_match($prg, $word, $url))
{
echo preg_replace($prg, "<a href=http://$url[0]>{$url[0]}</a>", $word);
}
else
{
echo $word;
}
To better clarify the issue:
I have a HTML code that have some tags. I want some words in that, converted to some links. But if it is a another link does not convert. See below advanced example for special word you that we want linked to the google:
This is a sample text.
Hello?! How are you?!
Are you ready?!
should be convert to:
This is a sample text.
Hello?! How are you?!
Are you ready ?!
Note that the first you changed, but that second you was not changed, because it's in the another <a> tag.
Answer:
Because of this work has issue with regular expression, this problem can solve without regular expression. Here a simple solution is given:
$data = 'Hello! This is a sample text. <br/>'.
'Hello! This is a sample text. <br/>'.
'Hello! This is a sample text. <br/>'.
'Hello! This is a sample text. <br/>'.
'Hello! This is a sample text.';
$from = " is ";
$to = '<a href="http://www.google.com" > '.$from.' </a>';
echo $data;
$data = explode($from, $data);
echo "<br><br>";
echo $data[0];
$diff = 0;
for($i=1; $i<count($data); $i++){
$n = substr_count($data[$i-1], '<a ') + substr_count($data[$i-1], '<A ');
$m = substr_count($data[$i-1], '</a>') + substr_count($data[$i-1], '</A>');
$diff += $n-$m;
if($diff==0)
echo $to.$data[$i];
else
echo $from.$data[$i];
}
Related
I have a search String: $str (Something like "test"), a wrap string: $wrap (Something like "|") and a text string: $text (Something like "This is a test Text").
$str is 1 Time in $text. What i want now is a function that will wrap $str with the wrap defined in $wrap and output the modified text (even if $str is more than one time in $text).
But it shall not output the whole text but just 1-2 of the words before $str and then 1-2 of the words after $str and "..." (Only if it isn`t the first or last word). Also it should be case insensitive.
Example:
$str = "Text"
$wrap = "<span>|</span>"
$text = "This is a really long Text where the word Text appears about 3 times Text"
Output would be:
"...long <span>Text</span> where...word <span>Text</span> appears...times <span>Text</span>"
My Code (Obviusly doesnt works):
$tempar = preg_split("/$str/i", $text);
if (count($tempar) <= 2) {
$result = "... ".substr($tempar[0], -7).$wrap.substr($tempar[1], 7)." ...";
} else {
$amount = substr_count($text, $str);
for ($i = 0; $i < $amount; $i++) {
$result = $result.".. ".substr($tempar[$i], -7).$wrap.substr($tempar[$i+1], 0, 7)." ..";
}
}
If you have a tipp or a solution dont hesitate to let me know.
I have taken your approach and made it more flexible. If $str or $wrap changes you could have escaping issues within the regex pattern so I have used preg_quote.
Note that I added $placeholder to make it clearer, but you can use $placeholder = "|" if you don't like [placeholder].
function wrapInString($str, $text, $element = 'span') {
$placeholder = "[placeholder]"; // The string that will be replaced by $str
$wrap = "<{$element}>{$placeholder}</{$element}>"; // Dynamic string that can handle more than just span
$strExp = preg_quote($str, '/');
$matches = [];
$matchCount = preg_match_all("/(\w+\s+)?(\w+\s+)?({$strExp})(\s+\w+)?(\s+\w+)?/i", $text, $matches);
$response = '';
for ($i = 0; $i < $matchCount; $i++) {
if (strlen($matches[1][$i])) {
$response .= '...';
}
if (strlen($matches[2][$i])) {
$response .= $matches[2][$i];
}
$response .= str_replace($placeholder, $matches[3][$i], $wrap);
if (strlen($matches[4][$i])) {
$response .= $matches[4][$i];
}
if (strlen($matches[5][$i]) && $i == $matchCount - 1) {
$response .= '...';
}
}
return $response;
}
$text = "text This is a really long Text where the word Text appears about 3 times Text";
string(107) "<span>text</span> This...long <span>text</span> where...<span>text</span> appears...times <span>text</span>"
To make the replacement case insensitive you can use the i regex option.
If I understand your question correct, just a little bit of implode and explode magic needed
$text = "This is a really long Text where the word Text appears about 3 times Text";
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
If you specifically need to render the span tags using HTML, just write it that way
$arr = explode("Text", $text);
print_r(implode('<span>Text</span>', $arr));
Use patern below to get your word and 1-2 words before and after
/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i
demo
In PHP code it can be:
$str = "Text";
$wrap = "<span>|</span>";
$text = "This is a really long Text where the word Text appears about 3 times Text";
$temp = str_replace('|', $str, $wrap); // <span>Text</span>
// find patern and 1-2 words before and after
// (to make it casesensitive, delete 'i' from patern)
if(preg_match_all('/((\w+\s+){1,2}|^)text((\s+\w+){1,2}|$)/i', $text, $match)) {
$res = array_map(function($x) use($str, $temp) { return '... '.str_replace($str, $temp, $x) . ' ...';}, $match[0]);
echo implode(' ', $res);
}
I have been asked by an interviewer for a test:
$string = "This is sample string";
// Output: "string_sample_is_This";
what does this question mean..?
I assumed that he was asking about a simple echo, am I right or would he expected something else from me ?
<?php
$string = "This is sample string";
echo $string;
?>
He definetly asked for something else ...
<?php
$string = explode(" ","This is sample string");
$string = array_reverse($string);
$string = implode("_",$string);
echo $string;
?>
More :
PHP explode()
PHP array_reverse()
PHP implode()
That looks more like you are being asked to reverse the order of the tokens in the string and replace the delimiter from single spaces to the _ character. I would assume that or something similar to such was being asked.
No he told to reverse the sentence and echo the string.
<?php
$string = "This is sample string";
$string1 = '';
$string_array = explode(' ',$string);
$count = count($string_array) - 1;
for($i=$count; $i>=0; $i--)
{
if($i == 0)
{
$string1 .= $string_array[$i];
}
else
{
$string1 .= $string_array[$i]."_";
}
}
echo $string1;
?>
I have a bunch of text and i want to highlight some words on that text. I've search the stackoverflow website and came up with something that almost work.
PHP
function highlighter($str, $arr_word)
{
foreach($arr_word as $vword) {
$text = preg_replace("|($vword)|Ui", "<span class=highlight>$1</span>", $str);
}
return $text;
}
$lyrics = 'hello looking for';
$arr_accepted_keyword = array('hello', 'for');
echo highlighter($lyrics, $arr_accepted_keyword);
For some reason, it always highligths the last word, and not all the words. Why?
The problem is that you're highlighting each word in the original string, not the updated string.
function highlighter($str, $arr_word)
{
foreach($arr_word as $vword) {
$str = preg_replace("/($vword)/Ui", "<span class=highlight>$1</span>", $str);
}
return $str;
}
$lyrics = "hello, is it me you're looking for?";
$arr_accepted_keyword = array('hello', 'for');
echo highlighter($lyrics, $arr_accepted_keyword);
// "<span class=highlight>hello</span>, is it me you're looking <span class=highlight>for</span>?"
I have a markdown text content which I have to replace without using library functions.So I used preg replace for this.It works fine for some cases.For cases like heading
for eg Heading
=======
should be converted to <h1>Heading</h1> and also
##Sub heading should be converted to <h2>Sub heading</h2>
###Sub heading should be converted to <h3>Sub heading</h3>
I have tried
$text = preg_replace('/##(.+?)\n/s', '<h2>$1</h2>', $text);
The above code works but I need to have count of hash symbol and based on that I have to assign heading tags.
Anyone help me please....
Try using preg_replace_callback.
Something like this -
$regex = '/(#+)(.+?)\n/s';
$line = "##Sub heading\n ###sub-sub heading\n";
$line = preg_replace_callback(
$regex,
function($matches){
$h_num = strlen($matches[1]);
return "<h$h_num>".$matches[2]."</h$h_num>";
},
$line
);
echo $line;
The output would be something like this -
<h2>Sub heading</h2> <h3>sub-sub heading</h3>
EDIT
For the combined problem of using = for headings and # for sub-headings, the regex gets a bit more complicated, but the principle remains the same using preg_replace_callback.
Try this -
$regex = '/(?:(#+)(.+?)\n)|(?:(.+?)\n\s*=+\s*\n)/';
$line = "Heading\n=======\n##Sub heading\n ###sub-sub heading\n";
$line = preg_replace_callback(
$regex,
function($matches){
//var_dump($matches);
if($matches[1] == ""){
return "<h1>".$matches[3]."</h1>";
}else{
$h_num = strlen($matches[1]);
return "<h$h_num>".$matches[2]."</h$h_num>";
}
},
$line
);
echo $line;
Whose Output is -
<h1>Heading</h1><h2>Sub heading</h2> <h3>sub-sub heading</h3>
Do a preg_match_all like this:
$string = "#####asdsadsad";
preg_match_all("/^#/", $string, $matches);
var_dump ($matches);
And based on count of matches you can do whatever you want.
Or, use the preg_replace_callback function.
$input = "#This is my text";
$pattern = '/^(#+)(.+)/';
$mytext = preg_replace_callback($pattern, 'parseHashes', $input);
var_dump($mytext);
function parseHashes($input) {
var_dump($input);
$matches = array();
preg_match_all('/(#)/', $input[1], $matches);
var_dump($matches[0]);
var_dump(count($matches[0]));
$cnt = count($matches[0]);
if ($cnt <= 6 && $cnt > 0) {
return '<h' . $cnt . ' class="if you want class here">' . $input[2] . '</h' . $cnt . '>';
} else {
//This is not a valid h tag. Do whatever you want.
return false;
}
}
I have a small function which goes through a bunch of text and looks for any urls in text form and converts them into html a's:
e.g
normal text lipsum etc http://www.somewebsitelink.com lipsum lipsum
becomes:
normal text lipsum etc http://www.somewebsitelink.com lipsum lipsum
My function is as follows:
function linkify($text)
{
$text = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9#:%_\+.~#?&//=]+)',
'<a target="_blank" href="\\1">\\1</a>', $text);
$text = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9#:%_\+.~#?&//=]+)',
'\\1<a target="_blank" href="http://\\2">\\2</a>', $text);
return $text;
}
This is all works ok, but where I use this function and print out the html is in a limited width space and sometimes links end up much bigger then can fit in the space and I end up with overflow.
I'm wondering how I might go about doing 2 things:
a. remove the unecessary from the the text ie 'http://' so I would end up with
www.somewebsitelink.com
and
b. If the text is greater than 20 characters, cut out everything after it and put in a few dots. e.g:
www.somewebsitelin...
I'm wondering if I might have to do this without using regular expressions, but then again my understanding of reg exp is fairly limited.
$link = 'http://www.somewebsitelink.com';
function linkify($text, $maxLen = 15)
{
return preg_replace_callback('(((f|ht){1}tp://)([-a-zA-Z0-9#:%_\+.~#?&//=]+))', function($t) use ($maxLen) {
if ( strlen($t[3]) > $maxLen)
$t[3] = substr_replace($t[3], '...', $maxLen);
return sprintf('<a target="_blank" href="%s">%s</a>', $t[0], $t[3]);
}, $text);
}
header('content-type: text/plain');
echo linkify($link);
Code for PHP <= 5.2
$link = 'http://www.somewebsitelink.com';
function linkify($text, $maxLen = 15)
{
$funcBody = <<<FUNC
if ( strlen(\$t[3]) > \$maxLen)
\$t[3] = substr_replace(\$t[3], '...', \$maxLen);
return sprintf('<a target="_blank" href="%s">%s</a>', \$t[0], \$t[3]);
FUNC;
$func = create_function(
'$t, $maxLen =' . $maxLen,
$funcBody
);
return preg_replace_callback('(((f|ht){1}tp://)([-a-zA-Z0-9#:%_\+.~#?&//=]+))', $func, $text);
}
header('content-type: text/plain');
echo linkify($link);
Results in
<a target="_blank" href="http://www.somewebsitelink.com">www.somewebsite...</a>
I think this will do what you need. It takes a url as its only paramater and removes the leading 'http://www." then returns the string if it is less than 20 characters. if it is more than 20 characters it returns the first 17 characters and appends '...'.
function get_formatted_url($url){
$url = trim($url);
$url = str_replace("http://www.", "", strtolower($url));
if(strlen($url) > 20){
return substr($url, 0, 16) . '...';
}else{
return $url;
}
}
Edit: An example using preg_replace_callback()
function get_formatted_url($url){
$url = $url[0];
$formatted_url = trim($url);
$formatted_url = str_replace("http://www.", "", strtolower($formatted_url));
if(strlen($formatted_url) > 20){
return '<a href="'.$url.'" />'. substr($formatted_url, 0, 16) . '... </a> ';
}else{
return '<a href="'.$url.'" />'. $formatted_url . '</a> ';
}
}
function linkify($text){
$reg = '(((f|ht)tp://)[-a-zA-Z0-9#:%_\+.~#?&//=]+)';
$text = preg_replace_callback($reg, "get_formatted_url", $text);
return $text;
}
$text = "abcd http://www.abc.com?hg=alkdjfa;lkdjfa;lkdjfa;lkdsjfa;ldks abcdefg http://www.abc.com";
echo linkify($text);
Use php substr function. For example:
<?php substr($text,0,10);?>