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);?>
Related
I have some code that outputs a title and a description for a list of posts. I am trying to limit the length of text for both. The title is $story->title, and outputs just fine. However the description, represented by $story->excerpt in the code, contains html tags in the database. The limit_text function seems to strip these tags from the text. I think I need to limit the characters differently or need a function to allow those tags to work.
I have tried some functions that allows the tags to be seen but not function properly. But I am new to php in general so I don't know many functions.
<?php
foreach($stories as $story) {
echo '<h2>'.limit_text($story->title, 80).'</h2>';
if(!empty($story->excerpt)) {
echo '<p>'.limit_text($story->excerpt, 150).'</p>';
} else {
echo limit_text($story->body, 150);
}
}
?>
I found the function for limit_text
function limit_text($string, $limit = 140) {
$string = preg_replace('/<figcaption>.*?<\/figcaption>/','',$string);
$string = preg_replace('/<div class=\"wp_image_caption\">.*?<\/div>/','',$string);
$string = str_replace(' ','',$string);
$string = substr($string, strpos($string, "<p><strong>"));
$string = strip_tags($string);
$string = substr($string, 0, $limit);
$string = $string.'...';
return $string;
}
The reason why my tags were being stripped was the strip_tagsmethod right in the function. Duh. Hehe. Thanks for the comments.
Try this limit text function instead
public function limitText($text, $len)
{
$text = preg_match('#<\s*?b\b[^>]*>(.*?)</b\b[^>]*>#s', $text, $matches);
return "<b>" . substr($text,0, $len) . "</b>";
}
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];
}
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 currently have a code that finds and replaces urls into complete html links. It works fine but now i need to update it so that if there is image url then it should convert it into a html img tag and display it. Function im using now is...
function auto_link_text($text) {
$pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
$callback = create_function('$matches', '
$url = array_shift($matches);
$url_parts = parse_url($url);
return sprintf(\'<a rel="nowfollow" target="_blank" href="%s">%s</a>\', $url, $url);
');
return preg_replace_callback($pattern, $callback, $text);
}
Got it from...
How to add anchor tag to a URL from text input
Here is an example of the text i would to it to go through...
asdf
http://google.com/
asfd
http://yahoo.com/logo.jpg
http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1
http://youtube.com/logo.png
like it updated function to output...
asdf
<a rel="nowfollow" target="_blank" href="http://google.com/">http://google.com/</a>
asfd
<img src="http://yahoo.com/logo.jpg" class="example">
<a rel="nowfollow" target="_blank" href="http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1">http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1</a>
<img src="http://youtube.com/logo.png" class="example">
Big thanks in advance!
You can use this for example:
function create_anchor_tag($url, $text = false) {
if ($text===false) $text = $url;
return '<a rel="no-follow" target="_blank" href="' . $url . '">'
. $text . '</a>';
}
function create_image_tag($url) {
return '<img src="' . $url . '"/>';
}
function auto_link_text($text) {
$pattern = '~\b(?:(?:ht|f)tps?://|www\.)\S+(?<=[\PP?])~i';
$callback = function ($m) {
$img_ext = array('jpg', 'jpeg', 'gif', 'png');
$path = parse_url($m[0], PHP_URL_PATH);
$ext = substr(strrchr($path, '.'), 1);
if (in_array(strtolower($ext), $img_ext))
return create_image_tag($m[0]);
return create_anchor_tag($m[0]);
};
return preg_replace_callback($pattern, $callback, $text);
}
I used several functions to make it more clea[rn], but you can easily adapt it as you like.
Here is the nice post about the best suitable regex pattern for valid URL. I picked one from there to group all the URLs.
Online demo
Steps to follow:
simply extract the url.
put a check on the url and based on your own logic substitute the tag as shown in demo.
sample code: (get all the valid urls in groups. get it from index 1)
$re = "/(([A-Za-z]{3,9}:(?:\\/\\/)?(?:[-;:&=\\+\\$,\\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\\+\\$,\\w]+#)[A-Za-z0-9.-]+)((?:\\/[\\+~%\\/.\\w-_]*)?\\??(?:[-\\+=&;%#.\\w_]*)#?(?:[\\w]*))?)/";
$str = "...";
preg_match_all($re, $str, $matches);
sample code: (substitute anchor tag (or what ever you want to add))
$re = "/(([A-Za-z]{3,9}:(?:\\/\\/)?(?:[-;:&=\\+\\$,\\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\\+\\$,\\w]+#)[A-Za-z0-9.-]+)((?:\\/[\\+~%\\/.\\w-_]*)?\\??(?:[-\\+=&;%#.\\w_]*)#?(?:[\\w]*))?)/";
$str = "...";
$subst = '$1';
$result = preg_replace($re, $subst, $str);
I have a problem with a PHP breadcrumb function I am using, when the page name is very long, it overflows out of the box, which then looks really ugly.
My question is, how can I achieve this: "This is a very long string" to "This is..." with PHP?
Any other ideas on how I could handle this problem would also be appreciated, thanx in advance!
Here is the breadcrumb function:
function breadcrumbs() {
// Breadcrumb navigation
if (is_page() && !is_front_page() || is_single() || is_category()) {
echo '<ul class="breadcrumbs">';
echo '<li class="front_page">'.get_bloginfo('name').' <span style="color: #FFF;">»</span> </li>';
if (is_page()) {
$ancestors = get_post_ancestors($post);
if ($ancestors) {
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $crumb) {
echo '<li>'.get_the_title($crumb).' <span style="color: #FFF;">»</span> </li>';
}
}
}
if (is_single()) {
$category = get_the_category();
echo '<li>'.$category[0]->cat_name.'</li>';
}
if (is_category()) {
$category = get_the_category();
echo '<li>'.$category[0]->cat_name.'</li>';
}
// Current page
if (is_page() || is_single()) {
echo '<li class="current">'.get_the_title().'</li>';
}
echo '</ul>';
} elseif (is_front_page()) {
// Front page
echo '<ul class="breadcrumbs">';
echo '<li class="front_page">'.get_bloginfo('name').'</li>';
echo '<li class="current">Home Page</li>';
echo '</ul>';
}
}
If you want a more nice (word limited) trucation you can use explode to split the string by spaces and then append each word (array entry) until you've reached your max limit
Something like:
define("MAX_LEN", 15);
$sentance = "Hello this is a long sentance";
$words = explode(' ', $sentance);
$newStr = "";
foreach($words as $word) {
if(strlen($newStr." ".$word) >= MAX_LEN) {
break;
}
$newStr = $newStr." ".$word;
}
If you are working with UTF-8 as charset, I suggest using the mb_strimwidth method as it is multibyte safe and won´t mess up multibyte chars. It also appends a placeholder string like ... automatically, with substr you´d have to do that in an additional step.
Usage sample:
echo mb_strimwidth("Hello World", 0, 10, "...", "UTF-8"); // .. or some other charset
// outputs Hello W...
You can safely use substr.
and eventually wordwrap() to break long words
$string = "This is a very long string";
$newString = substr( $string, 0, 7)."...";
// Output = This is...
Ideally, it should be done on the client side. You can use CSS/JS for the same.
Set this CSS property: text-overflow: ellipsis.
However, it will work only in IE. To use the same in Firefox as well, you can do something like this.
If you do not mind javascript plugins, use one of the jQuery ellipsis plugin.
Edit: These methods will work even when dealing with unicode, which can be a bit tricky if you try to handle this using php. (Like substr function)
Edit 2: If your problem is just the overflowing text and you do not mind not having the "..." at the end then it is even more simple. Simply, use the CSS: text-overflow: hidden;.
You can truncate the string at max length and then search for the last space:
Multibyte safe (Requires PHP > = 4.2)
function mb_TruncateString($string, $length = 40, $marker = "...")
{
if (mb_strlen($string) <= $length)
return $string;
// Trim at given length
$string = mb_substr($string, 0, $length);
// Get the text before the last space
if(mb_ereg("(.*)\s", $string, $matches))
$string = $matches[1];
return $string . $marker;
}
Following is not multibyte safe
function TruncateString($string, $length = 40, $marker = "...")
{
if (strlen($string) <= $length)
return $string;
// Trim at given length
$string = substr($string, 0, $length);
// Get the text before the last space
if(preg_match("/(.*)\s/i", $string, $matches))
$string = $matches[1];
return $string . $marker;
}
You're after a truncate function. This is what I use:
/**
* #param string $str
* #param int $length
* #return string
*/
function truncate($str, $length=100)
{
$str = substr($str, $length);
$words = explode(' ', $str); // separate words into an array
array_pop($words); // discard last item, as 9/10 times it's a partial word
$str = implode(' ', $words); // re-glue the string
return $str;
}
And usage:
echo truncate('This is a very long page name that will eventually be truncated', 15);