I decided to, for fun, make something similar to markdown. With my small experiences with Regular Expressions in the past, I know how extremely powerful they are, so they will be what I need.
So, if I have this string:
Hello **bold** world
How can I use preg_replace to convert that to:
Hello <b>bold</b> world
I assume something like this?
$input = "Hello **bold** world";
$output = preg_replace("/(\*\*).*?(\*\*/)", "<b></b>", $input);
Close:
$input = "Hello **bold** world";
$output = preg_replace("/\*\*(.*?)\*\*/", "<b>$1</b>", $input);
I believe there is a PHP package for rendering Markdown. Rather than rolling your own, try using an existing set of code that's been written and tested.
Mmm I guess this could work
$output = preg_replace('/\*\*(.*?)\*\*/', '<b>$1</b>', $input);
You find all sequences **something** and then you substitute the entire sequence found with the bold tag and inside it (the $1) the first captured group (the brackets in the expression).
$output = preg_replace("/\*\*(.*?)\*\*/", "<b>$1</b>", $input);
Related
Imagine if:
$string = "abcdabcdabcdabcdabcdabcdabcdabcd";
How do I remove the repeated sequence of characters (all characters, not just alphabets) in the string so that the new string would only have "abcd"? Perhaps running a function that returns a new string with removed repetitions.
$new_string = remove_repetitions($string);
The possible string before removing the repetition is always like above. I don’t know how else to explain since English is not my first language. Other examples are,
$string = “EqhabEqhabEqhabEqhabEqhab”;
$string = “o=98guo=98guo=98gu”;
Note that I want it to work with other sequence of characters as well. I tried using Regex but I couldn't figure out a way to accomplish it. I am still new to php and Regex.
For details : https://algorithms.tutorialhorizon.com/remove-duplicates-from-the-string/
In different programming have a different way to remove the same or duplicate character from a string.
Example: In PHP
<?php
$str = "Hello World!";
echo count_chars($str,3);
?>
OutPut : !HWdelor
https://www.w3schools.com/php/func_string_count_chars.asp
Here, if we wish to remove the repeating substrings, I can't think of a way other than knowing what we wish to collect since the patterns seem complicated.
In that case, we could simply use a capturing group and add our desired output in it the remove everything else:
(abcd|Eqhab|guo=98)
I'm guessing it should be simpler way to do this though.
Test
$re = '/.+?(abcd|Eqhab|guo=98)\1.+/m';
$str = 'abcdabcdabcdabcdabcdabcdabcdabcd
EqhabEqhabEqhabEqhabEqhab
o98guo=98guo=98guo=98guo=98guo=98guo=98guo98';
$subst = '$1';
$result = preg_replace($re, $subst, $str);
echo $result;
Demo
You did not tell what exactly to remove. A "sequnece of characters" can be as small as just 1 character.
So this simple regex should work
preg_replace ( '/(.)(?=.*?\1)/g','' 'abcdabcdabcdabcdabcdabcd');
I have a document full of hex colours, as shown below.
#123 is a nice colour but #321 is also fine. However, #fe4918 isn't a bad either.
I'd like to rotate them round, so that #123 would become #231, effectively changing the colour scheme. #fe4918 would become #4918fe.
I know that with regular expressions, one can select the the hash tags but not much else.
You could use a regex to do it...
preg_replace('/#([\da-f])([\da-f])([\da-f])(?:([\da-f])([\da-f])([\da-f]))?/i', '#$2$5$3$6$1$4', $str)
CodePad
It works by matching case insensitive hexadecimal numbers 3 or 6 times, and then reverses them using the matched groups.
Alternatively you could match it with a simple regex and callback with preg_replace_callback() and use strrev(), but I think the above example is clear enough.
You can use the following to match:
#([\da-f]{2})([\da-f]{2})([\da-f]{2})|#(\d)(\d)(\d)
And replace with:
#\2\5\3\4\1\6
See RegEX DEMO
You can use a branch reset group to handle the two cases with the same capture group numbers:
$str = preg_replace('~#(?|([a-f\d]{2})([a-f\d]{4})|([a-f\d])([a-f\d]{2}))~i',
'#$2$1', $str);
You can use a combination of a regex and strrev():
#([a-f0-9]+)
In PHP this would be:
<?php
$string = "#123 is a nice colour but #321 is also fine. However, #fe4918 isn't a bad either.";
$regex = '~#([a-f0-9]+)~';
$string = preg_replace_callback(
$regex,
function($match) {
return '#'.strrev($match[1]);
},
$string
);
echo $string;
// #321 is a nice colour but #123 is also fine. However, #8194ef isn't a bad either.
?>
You can do this in regex alone, but the above logic seems very clear (and maintainable in a few months as well).
See a demo on ideone.com.
i have a string as follows:
$product_req = "CATEGORY-ACTIVE-8,CATEGORY-ACTIVE-4,ACTIVE-6,ACTIVE-9";
and i need a function that returns only the numbers preceded by "CATEGORY-ACTIVE-" (without the quotes) so in other words it should return: 8,4 and leave everything else out.
Is there any php function that can do this?
Thank you.
Use Preg_match_all and extract the first match
$input_lines="CATEGORY-ACTIVE-8,CATEGORY-ACTIVE-4,ACTIVE-6,ACTIVE-9"
preg_match_all("/CATEGORY-ACTIVE-(\d+)/", $input_lines, $output_array);
print_r(join(',',$output_array[1]));
output
8,4
Is there any php function that can do this?
Yes you can play around and achieve it with PHP Native functions by writing some code logic. But do it with Regular Expressions (to keep it simple and short).
Using PHP Functions..
<?php
$str = 'CATEGORY-ACTIVE-8,CATEGORY-ACTIVE-4,ACTIVE-6,ACTIVE-9';
$str=explode(',',$str);
$temparr=array();
foreach($str as $v)
{
if(strpos($v,'CATEGORY-ACTIVE-')!==false)
{
$temparr[]=str_replace('CATEGORY-ACTIVE-','',$v);
}
}
echo implode(',',$temparr); //"prints" 8,4
Use regular expressions and implode it atlast (Preferred way..)
<?php
$str = 'CATEGORY-ACTIVE-8,CATEGORY-ACTIVE-4,ACTIVE-6,ACTIVE-9';
preg_match_all('/CATEGORY-ACTIVE-(.*?),/', $str, $matches);
echo implode(',',$matches[1]); //8,4
I'd use a lookaround assertion to accomplish this:
(?<=CATEGORY-ACTIVE-)(\d+)
Visualization:
Code:
$str = 'CATEGORY-ACTIVE-8,CATEGORY-ACTIVE-4,ACTIVE-6,ACTIVE-9';
preg_match_all('/(?<=CATEGORY-ACTIVE-)(\d+)/', $str, $matches);
print_r($matches[1]);
Output:
Array
(
[0] => 8
[1] => 4
)
Demo
Yes there is, Feel free to explore the wonderful world of Regex!
http://il1.php.net/preg_match
I recommend you do a bit of reading on this yourself as "getting the answers" when it comes to regex is a sin, You learn nothing from it.
I'm not uber experienced with it myself, but it's one of those things that you must learn 'hands on', theory won't cut it here.
in theory it would look like this
$str = 84838493849384938;
preg_match_all(/[8.4]/, $str);
You can also go play around with REgex at this site http://www.phpliveregex.com/
This is now mostly academic as I can achieve the same result other ways, but… it’s been bugging me, and I’m sure is possible somehow with regex.
I want to use PHP’s preg_replace to replace content thus:
Content: “String <tag>This is some content, which contains newlines and quotation marks.</tag> and other unrelated content”.
Regex: /<tag>(.*)<\/tag>/sU
Replace: “String of other content, including matched pattern $1”
However the problem is, I want to strip out any newlines and/or quotation marks found between the elements. What regex would allow me to do this?
PHPs preg_replace() does a one-pass processing of the subject. You can actually specify an array of patterns and replacements, however only one will match on each part of the subject string. There certainly is no solution using a singel regex, since this problem is not amongst the regular languages. Theoretical computer science teaches that you need a stateful automat for such task. A regex is to primitive.
Not easy, but possible.
Try this PHP code:
function myFn($a, $b, $c) {
$b = preg_replace("!(?:\\\'|[\"\n\r])!", '', $b);
return "BEGIN " . $b . " END";
}
$s = "abc <tag>def \n ghi 'jkl' mno \"pqr\" stu</tag> vwx";
$s = preg_replace('!(<tag>)(.*?)(</tag>)!ise', 'myFn("$1", "$2", "$3")', $s);
print $s;
Output:
abc BEGIN def ghi jkl mno pqr stu END vwx
Test this code here.
As arkascha pointed out, this is not really a problem that can easily be done in one pass.
It could be done in one step in Perl:
use strict;
use warnings;
my $string = "blah <tag> foo \"bar \n </tag> baz";
$string =~ s/(?<=\<tag\>)([^<]+)(?=\<\/tag\>)/$_=$1;s|[\n\"]||gs;$_/ges;
print $string;
This takes advantage of the fact that Perl lets you use code to generate the replacement string.
I don't know whether something similar could be done in PHP. This is not a good real-world code design anyway. But it is fun.
I've been looking all over the internet for some useful information and I think I found too much. I'm trying to understand regular expressions but don't get it.
Lets for instance say $data="A bunch of text [link=123] another bunch of text.", and it should get replaced with "< a href=\"123.html\">123< /a>".
I've been trying around a lot with code similar to this:
$find = "/[link=[([0-9])]/";
$replace = "< a href=\"$1\">$1< /a>";
echo preg_replace ($find, $replace, $data);
but the output is always the same as the original $data.
I think I have to see something relevent to my problem understand the basics.
Remove the extra [] around the (), and add + after the [0-9] to quantify it. Also, escape the [] that make up the tag itself.
$find = "/\[link=(\d+)\]/"; // "\d" is equivalent to "[0-9]"
$replace = "$1";
echo preg_replace($find,$replace,$data);
The regex would be \[link=([\d]+)\]
A good source for an quick overview of regular expression can you find here http://www.regular-expressions.info/
When you really interested in the power of regular expression, you should buy this book: Mastering Regular Expressions
A good Programm to test your RexEx on a Windows Client is: RegEx-Trainer
You are missing the + quantifier and as a result of this your pattern matches if there is a single digit following link=.
And there is an extra pair of [..] as a result of this the outer [...] will be treated as the character class.
You also forgot the escape the closing ].
Solution:
$find = "/[link=([0-9]+)\]/";
<?php
$data= "A bunch of text [link=123] another bunch of text.";
$find = '/\[link=([0-9]+?)\]/';
echo preg_replace($find, "$1", $data);