Matching text between braces in PHP - php

In direct follow-up to this previous question, how can I pull the text (and the braces if possible) out as a match using PHP?
Specifically, I am writing a Wordpress plugin and am looking to reformat all text between two curly braces (a quasi wiki-marking).
I've followed the steps outlined in another previous question I asked, and have the matching part working - it's the match I need help with.
Example:
This is some {{text}} and I want to reformat the items inside the curly braces
Desired output:
This is some *Text fancified* and I want to reformat the items inside the curly braces
What I have (that is not working):
$content = preg_replace('#\b\{\{`.+`\}\}\b#', "<strong>$0</strong>", $content);
If matching including the braces is too difficult, I can match using the braces as offsets, and then remove the 'offending' braces afterwards, too, using a more simple text-match function.

$content = preg_replace('/{([^{}]*)}/', "<strong>$1</strong>", $content);

You need to form a match group using ( round braces ).
preg_replace('#\{\{(.+?)\}\}#', "<strong>$1</strong>",
Whatever (.+?) matches then can be used as $1 in the replacement string. This way you have the enclosing {{ and }} already out of the way. Also \b was redundant.

Related

Regular Expression for anything enclosed in double squar bracket

I have been trying to extract some strings or any kinds of values which are enclosed in double squar bracket. i.e. [[hello world]] or [[12_ nine]] etc. That's mean anything but which are enclosed in two squar bracket. Please check this URL, where I tried. However, I am explaining below what I did:
/\[[^\]]*\]]/
This pattern can validate anything inside [[]]. My problem is, it validate also []]. I am giving two examples what this parttern validate [[Welcome]] [v2.0]]. I need second example should not be validated. See the URL, you can understand better.
You need this:
/\[\[[^\]]*\]\]/
Here's how it's defined:
First two (escaped) brackets: \[\[
Then something that's not brackets: [^\]]*
Then two closing brackets: \]\] (you could keep them unescaped too, it's a matter of style)
Note that it won't match strings having square brackets in the middle (e.g. [[ A [B] C]]). If you want to allow those strings, use
/\[\[.*?\]\]/
If that must be the whole string, as seems to be from your comment below, use
/^\[\[.*?\]\]$/ (if you want to allow brackets inside)
/^\[\[[^\]]*\]\]$/ (if you don't)
^ an $ are end of string anchors and let you test the whole string.
Try this regex
\[{2}[^\[\]]+\]{2}
try this Demo
Explanation
\[{2} I want exactly [[
\[{2} I want exactly ]]
[^\[\]]+ I want anything that is not [ or ] repeated one or more times
and if you want to catch only between two brackets
(?<=[^\[]\[{2})[^\[\]]+(?=\]{2}(?!\]))
try this Demo

Regular expression matching unescaped paired brackets and nested function calls

Here's the problem: given a string like
"<p>The price for vehicles {capitalize(pluralize(vehicle))} is {format_number(value, language)}</p><span>{employee_name}</span><span>\{do not parse me}</span>"
I need (1) a regex pattern in PHP that matches all values between un-escaped pairs of curly brackets and (2) another regex pattern that matches function calls and nested function calls (once the first pattern is matched). Of course, if I could use one regex only for both tasks that would be awesome.
By the way, I can't use Smarty, Twig or any other library - that's the only reason I have to build a parsing mechanism myself.
Thanks a ton!
Solution
(1) A partial solution for the first problem can be found here. Basically, we use the regex (?={((?:[^{}]++|{(?1)})++)}) and find the matches at index 1 of the resulting array.
It's partial because I still need to find a way of ignoring escaped braces, though.
(2) I'm considering the use of recursive regex, as suggested by Mario. Will post result here.
Thanks, guys!
Copying the answer from the comments in order to remove this question from the "Unanswered" filter:
This appears to be what you're looking for:
(?<!\\){([^(){}]+)\(((?:[^(){}]+|\(((?2))\))*)\)}
Link: http://www.regex101.com/r/uI4qN0
~ answer per Jerry
Note: For comparison - simply ignoring escaped braces is accomplished by adding a negative lookahead (?<!\\) to the beginning of the expression, like so:
(?<!\\)(?={((?:[^{}]++|{(?1)})++)})

PHP: What do the curly braces in $variable{0} do?

I was going through a codebase and came across a line I had a question about. It's something I haven't seen before and I was wondering if someone could explain it for me. Here's the code:
$variableName = $array[1];
$variableName{0} = strtolower($variableName{0});
$this->property = $variableName;
What are the curly braces being used for? I've used curly braces to define variables as variable names before, but is this the same thing? I can't seem to find any resources online that explain it, but I'm not sure if I'm searching for the right thing.
access the single byte with that index {0} => first char (in non-utf8 string)
you could simply test it with:
$var='hello';
echo $var{0};
It's setting the first character of the string to lower case. It's a string shortcut operator, functioning the same as this:
<?php
$variableName = strtolower(substr($variableName, 0, 1)) . substr($variableName, 1)
Curly braces {} work the same as square brackets [], for array or string indexing. I'm guessing it is borrowed from perl, in which the square brackets are used for arrays and braces are used for hashes. But in PHP arrays and hashes are the same thing.

I just need one line of Regex code edited

the following code works but how can it be edited to only detect the first curly brace after an end parenthesis?
'/\{(([^{}]*|(?R))*)\}/'
Example:
if (1==1)
{
echo "testing {$username}";
}
The problem is that it detects ALL curly brackets, even the one surrounding the $username variable. So I think a solution would be to detect is there is a ) before the first curly bracket. I tried about 20 different things myself but cannot get it to work. How can it be edited to only detect ) { Oh and please add code if there are spaces and tabs involved inbetween the first curly bracket and end parenthesis if that matters. Thanks.
You can use:
\)\s*\{
as part of your pattern to detect simple cases like your example. Note that you can't use a positive lookbehind of variable length though, so you can't alter it to (?<=)\s*){
My pattern will still pick up code that is commented out though, and won't detect code that has a comment between the ) and the {. You wouldn't want to use a regex to try to detect such cases.

Parse for square brackets with regular expressions

I've always had a difficult time with regular expressions. I've searched for help with this, but I can't quite find what I'm looking for.
I have blocks of text that follow this pattern:
[php]
... any type of code sample here
[/php]
I need to:
check for the square brackets, which can contain any number of 20-30 programming language names (php, ruby, etc.).
need to grab all code in between the opening and closing bracket.
I have worked out the following regular expression:
#\[([a-z]+)\]([^\[/]*)\[/([a-z]+)\]#i
Which matches everything pretty well. However, it breaks when the code sample contains square brackets. How do I modify it so that any character between those opening/closing braces will be matched for later use?
This is the regex you want. It matches where the tags are even too, so a php tag will only end a php tag.
/\[(\w+)\](.*?)\[\/\1\]/s
Or if you wanted to explicitly match the tags you could use...
$langs = array('php', 'python', ...);
$langs = implode('|', array_map('preg_quote', $langs));
preg_match_all('/\[(' . $langs . ')\](.*?)\[\/\1\]/s', $str, $matches);
The following will work:
\[([a-z]+)\].*\[/\1\]
If you don't want to remove the greediness, you can do:
\[([a-z]+)\].*?\[/\1\]
All you have to do is to check that both the closing and opening tags have the same text (in this case, that both are the same programming language), and you do that with \1, telling it to match the previously matched Group number 1: ([a-z]+)
Why don't you use something like below:
\[php\].*?\[/php\]
I don't understand why you want to use [a-z]+ for the tags, there should be php or a limited amount of other tags. Just keep it simple.
Actually you can use:
\[(php)\].*?\[/(\1)\]
so that you can match the opening and closing tags. Otherwise you will be matching random opening and closing. Add others like, I don't know, js etc as php|js etc.
Use a backreference to refer to a match already made in the regular expression:
\[(\w+)\].*?\[/\1\]

Categories