I want to make links using shortcuts following the pattern: controller/#/id. For example: a#3 must be rewritten to /actions/view/3, and t#28 must be a link to /tasks/view/28. I think preg_replace is an "easy" way to achieve this, but I'm not that good with regular expressions and I don't know how to "reuse" the digits from the search-string within the result. I think I need something like this:
$search = array('/a#\d/', '/t#\d/');
$replace = array('/actions/view/$1', '/tasks/view/$1');
$text = preg_replace($search, $replace, $text);
Can someone point me in the right direction?
You can "reuse" the numbers from the search strings using capturing groups, denoted by brackets ().
Try this -
$text = "a#2 a#3 a#5 a#2 t#34 t#34 t#33 t#36";
$search = array('/\ba#(\d+)\b/', '/\bt#(\d+)\b/');
$replace = array('/actions/view/$1', '/tasks/view/$1');
$text = preg_replace($search, $replace, $text);
var_dump($text);
/**
OUTPUT-
string '/actions/view/2 /actions/view/3 /actions/view/5 /actions/view/2 /tasks/view/34 /tasks/view/34 /tasks/view/33 /tasks/view/36' (length=123)
**/
The above answer works, but if you need to add more of those search values, you can store those keys in separate array and you can use preg_replace_callback.This also does the same thing, but now, you only need to add more (alphabets)keys in the array and it will replace it accordingly. Try something like this-
$arr = Array(
"a"=> "/actions/view/",
"t"=> "/tasks/view/"
);
$text = preg_replace_callback("/\b([a-z]+)#(\d+)\b/", function($matches) use($arr){
var_dump($matches);
return $arr[$matches[1]].$matches[2];
},$text);
var_dump($text);
/**
OUTPUT-
string '/actions/view/2 /actions/view/3 /actions/view/5 /actions/view/2 /tasks/view/34 /tasks/view/34 /tasks/view/33 /tasks/view/36' (length=123)
**/
Since the number is not replaced you can use strtr (if it is not too ambigous) :
$trans = array('a#' => '/actions/view/', 't#' => '/tasks/view/');
$text = strtr($text, $trans);
if you can use this, it will be faster than processing a string two times with a regex.
Related
I have a doubt, it may be something simple but I have no knowledge to solve it.
I get a string in php
$ string = "[link = someUrl] Text [link]"
And I would like to turn this string into:
"<a href='someUrl'> Text <a/>"
How do I change the URL? and How Can I do the opposite?
Remember that the string belongs to a text with more strings of these gifts.
Short preg_replace solution:
$s = "[link=someUrl] Text [/link]";
$result = preg_replace('#\[[^=]+=([^]]+)\]([^[]+).*#', '<a href=\'$1\'>$2</a>', $s);
print_r($result);
The output (as web page source code):
<a href='someUrl'> Text </a>
You can use the following code
function transformText($string) {
preg_match("/\[link\=([^\]]*)\](.*?)\[\/link]/", $string, $matches);
$someUrl = $matches[1];
$text = $matches[2];
$newString = "<a href='$someUrl'>$text</a>";
return $newString;
}
$string = "[link=someUrl] Text [/link]"; // Test string
echo (transformText($string));
Live demo for the regex used : https://regex101.com/r/tzVfmH/4
Note : The above code works only if there's a single [link], [/link] pair.
If multiple occurrences are to be handled then its better to use regex search and replace, using php's preg_replace as suggested in RomanPerekhrest's answer.
Thanks to #s.d.a.p.e I've come a step close but I'm not quite there yet.
What I'm trying to do is replace all instances of a string in a block of text. I want to replace something like this:
user is ?user_id=34&first_name=Ralph so is ?user_id=1 also
With this:
user is /user/34/ so is /user/1/ also
Here is the preg_replace code I'm using:
$pattern = '#\?user_id=([0-9]+)#';
$replace = '/user/$1/';
echo preg_replace($pattern,$replace,$string);
With that pattern I end up with this:
user is /user/34/&first_name=Ralph so is /user/1/ also
Thanks again.
try this:
$string = "user is ?user_id=34&first_name=Ralph so is ?user_id=1 also";
$result = preg_replace('/\?(user)_id=(\d+)(.*?)(?! )/i', '/$1/$2/$3', $string );
echo $result ;
Output:
user is /user/34/&first_name=Ralph so is /user/1/ also
DEMO
I'd use this:
$string = 'user is ?user_id=34&first_name=Ralph so is ?user_id=1 also';
$pattern = '#\?user_id=([0-9]+)\S*#';
$replace = '/user/$1/';
echo preg_replace($pattern, $replace, $string);
Where \S stands for any character that is not a space.
Output:
user is /user/34/ so is /user/1/ also
print preg_replace(
'#\?user_id=([0-9]+)\&(first_name=(?:.*))#',
'/user/$1?$2',
'?user_id=34&first_name=Ralph'
);
result :
/user/34?first_name=Ralph if get it right..
I need some special filtering to certain text all over my website, like below:
function special_text( $content ) {
$search_for = 'specialtext';
$replace_with = '<span class="special-text"><strong>special</strong>text</span>';
return str_replace( $search_for, $replace_with, $content );
}
add_filter('the_content', 'special_text', 99);
It's doing thing in an excellent way, BUT...
in content if there's any link like: <a title="specialtext" href="http://specialtext.com">specialtext</a> then the title and href texts also changed and the link becomes broken.
How can I make exception there?
Is there a way I can put some exceptions in an array and str_replace() simply skip 'em?
You should use regular expression and use function preg_replace() to replace matched string. Here is the full implementation of your special_text() function.
function special_text( $content ) {
$search_for = 'specialtext';
$replace_with = '<span class="special-text"><strong>special</strong>text</span>';
return preg_replace( '/<a.*?>(*SKIP)(*F)|'.$search_for.'/m', $replace_with, $content );
}
In the following regular expression first, using <a.*?> - everything between <a...> is matched and using (*SKIP)(*F)| it is skipped and then from anything else $search_for is matched (in your case it's specialtext).
Jezzabeanz quite got it except you can simplify it still with:
return preg_replace("/^def/", $replace_with, $content);
If you just want to change the text between the the a tags then a regular expression works wonders.
Here is something I used when I was pulling data from emails sent to me:
(?<=">)(.*?\w)(?=<\/a)
returns "specialtext"
It also returns "specialtext test" if there is whitespace.
Regular expressions are definitely the way to go.
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
print_r($matches);
?>
Source
And then do a replace on the returned matches.
How should one use preg_replace() to replace a string from 'aabbaacc' to 'abc'?
Currently, my code uses str_split() then array_unique() then implode().
I think preg_replace() can achieve this also, but I don't know how.
Thank you for your help.
A regex that seems to work for me is /(.)(?=.*?\1)/. Please test it for yourself here:
http://regexpal.com/
I've also tested it with preg_replace('/(.)(?=.*?\1)/', '', 'aaabbbabc') which returns the expected abc.
Hope this helps :)
This is the closest I got. However, it's basically a copy of :
How do I remove duplicate characters and keep the unique one only in Perl?
<?php
$string = 'aabbaacc';
$new = preg_replace( '/(.)(?=.*?\1)/i','', $string );
echo $new;
?>
Unfortunately, it does not keep the string in the same order. I don't know if that is important to you or not.
try this
$string = 'dbbaabbbaac';
$new = preg_replace_callback( array("/(.)\\1+/"),function($M){print_r($M);return $M[1];}, $string );
$new = preg_replace_callback( array('/(.)(.?\\1)/i','/(.)(.*?\\1)/i'),function($M){return $M[1].trim($M[2],$M[1]);}, $new );
echo $new."\n";
output
dbac
or this with out Regex
$value="aabbaacc";
for($i=0;$i<strlen($value);$i++){
$out[$value[$i]]=$value[$i];
}
echo implode("",$out);
output:
abc
What I'm trying to do is, if it exists, remove an occurrence of text inside a 'shortcode', eg: Here's some content [shortcode]I want this text removed[/shortcode] Some more content to be changed to Here's some content [shortcode][/shortcode] Some more content.
It seems like a pretty simple thing to do but I can't figure it out.. =/
The shortcode will only show up once in the entire string.
Thanks in advance for help.
Try this:
$var = "Here's some content [shortcode]I want this text removed[/shortcode] Some more content";
$startTag = "[shortcode]";
$endTag = "[/shortcode]";
$pos1 = strpos($var, $startTag) + strlen($startTag);
$pos2 = strpos($var, $endTag);
$result = substr_replace($var, '', $pos1, $pos2-$pos1);
It's very easy to do with preg_replace(). For your purpose, use /\[shortcode\].*\[\/shortcode\]/ as pattern.
$replace = "[shortcode][/shortcode]";
$filteredText = preg_replace("/\[shortcode\].*\[\/shortcode\]/", $replace, $yourContent);
See http://php.net/manual/en/function.preg-replace.php for more details.
One can use strpos() to find the position of [substring] and [/substring] in your string and replace the text with a whitespace via substr_replace()
if you do not want to bother with regular expessions:
if you do have the [shortcode] tag inside the string, than it is really no problem: just use a nested use of substr:
substr($string,0,strpos($string,'[substring]')+11)+substr($string,strpos($string,'[/substring]'),strlen($string))
where the first substr cuts the string to the start of the string to cut and the second adds the remaining stuff of the string.
see here:
http://www.php.net/manual/en/function.substr.php
http://www.php.net/manual/en/function.strpos.php
use regex in php to get rid of it.
preg_replace (shortcode, urText, '', 1)
$string = "[shortcode]I want this text removed[/shortcode]";
$regex = "#\[shortcode\].*\[\/shortcode\]#i";
$replace = "[shortcode][/shortcode]";
$newString = preg_replace ($regex, $replace, $string, -1 );
$content = "Here's some content [shortcode]I want this text removed[/shortcode] Some more content to be changed to Here's some content [shortcode][/shortcode] Some more content";
print preg_replace('#(\[shortcode\])(.*?)(\[/shortcode\])#', "$1$3", $content);
Yields:
Here's some content [shortcode][/shortcode] Some more content to be changed to Here's some content [shortcode][/shortcode] Some more content