I am trying to learning something about PHP, and I don't know how to do it, something like this:
I have a string:
$text = 'This is your post number [postnumb], This is [postnumb], And this is your post number [postnumb].';
And with PHP I want to change the string [postnumb] to the number of post:
$textchanged = 'This is your post number 1, This is your post number 2, This is your post number 3.';
Any help for me? Thanks.
Using preg_replace(), you can use the 4th argument to limit the replacement to the first occurrence. Combine this with a loop that will run until there are no occurrences remaining, and you can achieve what you're after:
$text = 'This is your post number [postnumb], This is [postnumb], And this is your post number [postnumb].';
$i = 0;
while(true)
{
$prev = $text;
$text = preg_replace('/\[postnumb\]/', ++$i, $text, 1);
if($prev === $text)
{
// There were no changes, exit the loop.
break;
}
}
echo $text; // This is your post number 1, This is 2, And this is your post number 3.
str_replace("[postnumb]", 1, $text);
You can't set different numbers for [postnumb] using str_replace() (unless you do it manually for substrings).
preg_replace() should help you for that case, or using different tags for different numbers (like [postnumb2] and [postnumb]).
Related
I am sorry if this is a very stupid question, or an obvious newbie mistake - but I as basic as this is , I hardly never used the do - while loop before (I know - I can not comprehend it myself ! How is it possible that I managed to avoid it all those years ??)
so :
I want to select a number of words from the begining of a text paragraph.
I used the following code :
$no_of_char = 70;
$string = $content;
$string = strip_tags(stripslashes($string)); // convert to plaintext
$string = substr($string, 0, strpos(wordwrap($string, $no_of_char), "\n"));
Which Kind of works, but the problem is that sometimes it gives EMPTY results.
I would think that is because the paragraph contains spaces, empty lines , and / or carriage returns...
So I am trying to make a loop condition that will continue to try until the length of the string is at least X characters ..
$no_of_char = 70; // approximation - how many characters we want
$string = $content;
do {
$string = strip_tags(stripslashes($string)); // plaintext
$string = substr($string, 0, strpos(wordwrap($string, $no_of_char), "\n")); // do not crop words
}
while (strlen($string) > 8); // this would be X - and I am guessing here is my problem
Well - obviously it does not work (otherwise this question would not be ) - and now it ALWAYS produces nothing .(empty string)
Try using str_word_count:
$words = str_word_count($string, 2);
2 - returns an associative array, where the key is the numeric
position of the word inside the string and the value is the actual
word itself
Then use array_slice:
$total_words = 70;
$selected_words = array_slice($words, 0, $total_words);
The most likely problem you have is that the string has blank lines at the start. You can easily get rid of them with ltrim(). Then use your original code to get the first actual newline.
The reason your loop didn't work is because you told it to reject anything that was longer than 8 characters.
I am trying to limit the amount of text/data is being shown from MySQL not MySQL LIMIT but limiting it on the actual page like most blogs do. After certain text point they just display ...more, I know there is a function to do this in PHP but I am unable to remember its name could some one help me out with it?
if(strlen($text)>1000){
$text=substr($text,0,1000).' Read more';
}
you should understand that it can cut words and tags too.
SELECT LEFT(content, 1000) FROM blog
If you load entire content for example 30 000 chars and do substr(), you are wasting memory in order to show only 1000.
You could use a function like this (taken from http://brenelz.com/blog/creating-an-ellipsis-in-php/):
function ellipsis($text, $max=100, $append='…')
{
if (strlen($text) <= $max) return $text;
$out = substr($text,0,$max);
if (strpos($text,' ') === FALSE) return $out.$append;
return preg_replace('/\w+$/','',$out).$append;
}
This won't cut a word in half like substr.
There are a few ways to do it, the easiest probably being substr()
$short = substr($long, 0, $max_len);
string substr ( string $string , int $start [, int $length ] )
It accepts two arguments. The first is the string that you would like to trim. The second is the length, in characters of what you'd like returned.
http://php.net/manual/en/function.substr.php
Apply the wrap() function to get your shortened text, and replace "99" with the number of characters you want to limit it to.
function wrap($string) {
$wstring = explode("\n", wordwrap($string, 99, "\n") );
return $wstring[0];
}
<?
$position=14; // Define how many character you want to display.
$message="You are now joining over 2000 current";
$post = substr($message, 0, $position);
echo $post;
echo "...";
?>
This result shows 14 characters from your message
I'm using the getExcerpt() function below to dynamically set the length of a snippet of text. However, my substr method is currently based on character count. I'd like to convert it to word count. Do I need to separate function or is there a PHP method that I can use in place of substr?
function getExcerpt()
{
//currently this is character count. Need to convert to word count
$my_excerptLength = 100;
$my_postExcerpt = strip_tags(
substr(
'This is the post excerpt hard coded for demo purposes',
0,
$my_excerptLength
)
);
return ": <em>".$my_postExcerpt." [...]</em>";}
}
Use str_word_count
Depending on the parameters, it can either return the number of words in a string (default) or an array of the words found (in case you only want to use a subset of them).
So, to return the first 100 words of a snippet of text:
function getExcerpt($text)
{
$words_in_text = str_word_count($text,1);
$words_to_return = 100;
$result = array_slice($words_in_text,0,$words_to_return);
return '<em>'.implode(" ",$result).'</em>';
}
If you want that your script should not ignore the period and comma and other punctuation symbols then you should adopt this approach.
function getExcerpt($text)
{
$my_excerptLength = 100;
$my_array = explode(" ",$text);
$value = implode(" ",array_slice($my_array,0,$my_excerptLength));
return
}
Note : This is just an example.Hope it will help you.Don't forget to vote if it help you.
I am relatively new to php, and hope someone can help me with a replace regex, or maybe a match replace I am not exactly sure.
I want to automatically bold the (second occurance of a match) and then make the 4th appearance of a match italic and then the 7th appearance of a match underlined.
This is basically for SEO purposes in content.
I have done some replacements with: and were thinking this should do the trick?
preg_replace( pattern, replacement, subject [, limit ])
I already know the word I want to use in
'pattern' is also a word that is already defined like [word].
`replacement` 'This is a variable I am getting from a mysql db.
'subject' - The subject is text from a db.
Lets say I have this content: This explains more or less what I want to do.
This is an example of the text that I want to replace. In this text I want to make the second occurance of the word example < bold. Then I want to skip the next time example occurs in the text, and make the 4th time the word example appears in italic. Then I want to skip the 5th time the word example appears in the text, as well as the 6th time and lastly wants to make the 7th time example appears in the text underline it. In this example I have used a hyperlink as the underline example as I do not see an underline function in the text editor. The word example may appear more times in the text, but my only requerement is to underline once, make bold once and make italic once. I may later descide to do some quotes on the word "example" as well but it is not yet priority.
It is also important for the code not to through an error if there is not atleast 7 occurances of the word.
How would I do this, any ideas would be appreciated.
You could use preg_split to split the text at the matches, apply the modifications, and then put everything back together:
$parts = preg_split('/(example)/', $str, 7, PREG_SPLIT_DELIM_CAPTURE);
if (isset($parts[3])) $parts[3] = '<b>'.$parts[3].'</b>';
if (isset($parts[7])) $parts[7] = '<i>'.$parts[7].'</i>';
if (isset($parts[13])) $parts[13] = '<u>'.$parts[13].'</u>';
$str = implode('', $parts);
The index formula for the i-th match is index = i · 2 - 1.
The regular expression itself cannot count, and the preg_ functions provide little help. You need a workaround. If you were to actually search for just a word, you might want to use string functions. Otherwise try:
// just counting
if (7 >= preg_match_all($pattern, $subject, $matches)) {
$cb_num = 0;
$subject = preg_replace_callback($pattern, "cb_ibu", $subject);
}
function cb_ibu($match) {
global $cb_num;
$match = $match[0];
switch (++$cb_num) {
case 2: return "<b>$match</b>";
case 4: return "<i>$match</i>";
case 7: return "<u>$match</u>";
default: return $match;
}
}
The trick is to have a callback which does the accounting. And there it's quite easy to add any rules.
That's an interesting question. My implementation would be:
function replace_exact($word, $tag, $string, $limit) {
$tag1 = '<'.$tag.'>';
$tag2 = '</'.$tag.'>';
$string = str_replace($word, $tag1.$word.$tag2, $string, 1);
if ($limit==1) return $string;
return str_replace($tag1.$word.$tag2,$word,$string,$limit-1);
}
Use it like this:
echo replace_exact('Example', 'b', $source_text, 2);
echo replace_exact('Example', 'i', $source_text, 4);
I don't know about how fast this will work, but it will be faster than preg_replace.
Basically I have a variable which contains a few paragraphs of text and I have a variable which I want to make bold within the paragraphs. (By wrapping <strong></strong> tags around it). The problem is I don't want to make all instances of the word bold, or else I'd just do a str_replace(), I want to be able to wrap the first, second, fourth, whatever instance of this text in the tags, at my own discretion.
I've looked on Google for quite awhile but it's hard to find any results related to this, probably because of my wording..
I guess that preg_replace() could do the trick for you. The following example should skip 2 instances of the word "foo" and highlight the third one:
preg_replace(
'/((?:.*?foo.*?){2})(foo)/',
'\1<strong>\2</strong>',
'The foo foo fox jumps over the foo dog.'
);
(Sorry, I forgot two questionmarks to disable the greediness on my first post. I edited them in now.)
You can probably reference 'Replacing the nth instance of a regex match in Javascript' and modify it to work for your needs.
Since you said you wanted to be able to define which instances should be highlighted and it sounds like that will be arbitrary, something like this should do the trick:
// Define which instances of a word you want highlighted
$wordCountsToHighlight = array(1, 2, 4, 6);
// Split up the paragraph into an array of words
$wordsInParagraph = explode(' ', $paragraph);
// Initialize our count
$wordCount = 0;
// Find out the maximum count (because we can stop our loop after we find this one)
$maxCount = max($wordCountsToHighlight);
// Here's the word we're looking for
$wordToFind = 'example'
// Go through each word
foreach ($wordsInParagraph as $key => $word) {
if ($word == $wordToFind) {
// If we find the word, up our count.
$wordCount++;
// If this count is one of the ones we want replaced, do it
if (in_array($wordCount, $wordCountsToHighlight)) {
$wordsInParagragh[$key] = '<strong>example</strong>';
}
// If this is equal to the maximum number of replacements, we are done
if ($wordCount == $maxCount) {
break;
}
}
}
// Put our paragraph back together
$newParagraph = implode(' ', $wordsInParagraph);
It's not pretty and probably isn't the quickest solution, but it'll work.