Extract content between first "]" and last "[" using regex? - php

Is it possible to have a PHP regex expression that extracts the content from the first ] to the last [?
For example if I had the following string:
$string = [shortcode]You write a shortcode by using ([])[/shortcode]
I would want to extract:
You write a shortcode by using brackets ([])
and store it in a variable. The content to be extracted could be anything. Thanks in advance.

You should be using capturing groups to make sure you match the closing tag.
\[(\w+)\].*?\[/\1\]
This will match a word inside [] and keep going until if finds the same word inside [/...].

Regexes are greedy by default, so this will do the job just fine:
/\](.*)\[/
To get this working in PHP properly, you would do something like this:
preg_match('/\](.*)\[/', $text, $matches);
$result = $matches[1];

this could make, what you need
[^\]]\](.*)\[[^\[]

This works:
preg_match( '#\](.*)\[#', $string, $matches);
print_r($matches);

Related

PHP preg_match exact match and get whats inside brackets

Lets say I have the following string:
"**link(http://google.com)*{Google}**"
And I want to use preg_match to find the EXACT text **link(http://google.com) but the text inside the brackets changes all the time. I used to use:
preg_match('#\((.*?)\)#', $text3, $match2);
Which would get what is inside the brackets which is good but if I had: *hwh(http://google.com)** it would get whats inside of that. So how can i get whats inside the brackets if, in front of the brackets has **link?
~(?:\*\*link\(([^\)]+)\))~ will match contents in the brackets for all inputs that look like **link(URL) but do not contain extra ) inside URLs. See the example on Regexr: http://regexr.com/3en33 . The whole example:
$text = '"**link(http://google.com)*{Google}**"
**link(arduino.cc)*{official Arduino site}';
$regex = '~(?:\*\*link\((?<url>[^)]+))~';
preg_match_all($regex, $text, $matches);
var_dump($regex, $matches['url']);
Here
preg_match("/\*\*link\((\D+)\)/",$text,$match);
Use a lookbehind operator ?<=
(?<=\*\*link)\((.*)\) gives you what's inside braces if the text behind is **link
Update:
Here's a PHP example
Here's a regex example

preg_replace with Regex - find number-sequence in URL

I'm a regex-noobie, so sorry for this "simple" question:
I've got an URL like following:
http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-146370543.aspx
what I'm going to archieve is getting the number-sequence (aka Job-ID) right before the ".aspx" with preg_replace.
I've already figured out that the regex for finding it could be
(?!.*-).*(?=\.)
Now preg_replace needs the opposite of that regular expression. How can I archieve that? Also worth mentioning:
The URL can have multiple numbers in it. I only need the sequence right before ".aspx". Also, there could be some php attributes behind the ".aspx" like "&mobile=true"
Thank you for your answers!
You can use:
$re = '/[^-.]+(?=\.aspx)/i';
preg_match($re, $input, $matches);
//=> 146370543
This will match text not a hyphen and not a dot and that is followed by .aspx using a lookahead (?=\.aspx).
RegEx Demo
You can just use preg_match (you don't need preg_replace, as you don't want to change the original string) and capture the number before the .aspx, which is always at the end, so the simplest way, I could think of is:
<?php
$string = "http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-146370543.aspx";
$regex = '/([0-9]+)\.aspx$/';
preg_match($regex, $string, $results);
print $results[1];
?>
A short explanation:
$result contains an array of results; as the whole string, that is searched for is the complete regex, the first element contains this match, so it would be 146370543.aspx in this example. The second element contains the group captured by using the parentheeses around [0-9]+.
You can get the opposite by using this regex:
(\D*)\d+(.*)
Working demo
MATCH 1
1. [0-100] `http://stellenanzeige.monster.de/COST-ENGINEER-AUTOMOTIVE-m-w-Job-Mainz-Rheinland-Pfalz-Deutschland-`
2. [109-114] `.aspx`
Even if you just want the number for that url you can use this regex:
(\d+)

How to get the contents of parenthesis by regex?

I want to get the contents of parenthesis within a string in PHP by regular expression. I tried this regex
preg_match_all('/\((.*)?\)/', $string, $match);
But this get the content between the first ( and last ). How can I get the content of every ( )separately to make the array of match?
You need to change the .* with [^\)]*
preg_match_all('/\(([^)]*)\)/', $string, $match);

RegEx Capture Group with PHP preg_match Not Returning Values

I'm trying to capture the text "Capture This" in $string below.
$string = "</th><td>Capture This</td>";
$pattern = "/<\/th>\r.*<td>(.*)<\/td>$/";
preg_match ($pattern, $string, $matches);
echo($matches);
However, that just returns "Array". I also tried printing $matches using print_r, but that gave me "Array ( )".
This pattern will only come up once, so I just need it to match one time. Can somebody please tell me what I'm doing wrong?
The problem is that you require a CR character \r. Also you should make the search lazy inside the capturing group and use print_r to output the array. Like this:
$pattern = "/<\/th>.*<td>(.*?)<\/td>$/";
You can see it in action here: http://codepad.viper-7.com/djRJ0e
Note that it's recommended to parse html with a proper html parser rather than using regex.
Two things:
You need to drop the \r from your regex as there is no carriage return character in your input string.
Change echo($matches) to print_r($matches) or var_dump($matches)

PHP Regex question

I'm trying to parse some text for example:
$text = "Blah blah [a]findme[/a] and [b]findmetoo[b], maybe also [z]me[/z].";
What I have now is:
preg_match_all("/[*?](.*?)[\/*?]/", $text, $matches);
Which doesn't work unfortunately.
Any ideas how to parse, return the node key and the corresponding node value?
Well firstly by you not putting () around your *? your not matching the tag name, and secondly, using [*?] will match multiple [ until the ] where you want to match inside, so you should be doing [(.*?)] and [\/(.*?)]
You would have to try something along the lines of:
/\[(.*?)\](.*?)\[\/(.*?)\]/is
this is not guaranteed to work but will get you closer.
you could also do:
/\[(.*?)\](.*?)\[\/\1\]/is
and then foreach result loop recursively until preg_match_all returns false, that's a possible way how to do nesting.
In order to match the same tags, you need a backreference:
This assumes no nesting, if you need nesting then let me know.
$matches = array();
if (preg_match_all('#\[([^\]]+)\](.+?)\[/\1\]#', $text, $matches)) {
// $matches[0] - entire matched section
// $matches[1] - keys
// $matches[2] - values
}
Incidentally, I do not know what you are going to do with this bbcode style work, but usually you would want to use preg_replace_callback() to deal with inline modification of this sort of text, with a regexp similar to the above.
Try:
$pattern = "/\[a\](.*?)\[\/a\]/";
$text = "Blah blah [a]findme[/a] and [b]findmetoo[b], maybe also [z]me[/z].";
preg_match_all($pattern, $text, $matches);
That should point you in the right direction.
I came up with this regex ((\[[^\/]\]).+?(\[\/[^\/]\])). Hope will work for you
I'm no regex monkey, but I think you need to escape those brackets and create groups to search for, as brackets don't return results (parentheses do):
preg_match_all("/\\[(*?)\\](.*?)\\[\(\/*?)\\]/", $text, $matches);
Hope this works!
Should your second example also be captured even though the [b] "tag" is not closed with the [\b] backslash 'b'. If tags should be properly closed then use
/\[(.*?)\](.*?)\[\/\1\]/
This will ensure that opening and closing tags match.
You can try this:
preg_match_all("/\[(.*?)\](.*?)\[\/?.*?\]/", $text, $matches);
See it
Changes made:
[ and ] are regex meta-characters
used to define character class. To
match literal [ and ] you need to
escape them.
To match any arbitrary text(without
newline) in non-greedy way you use
.*?.
To match the node key you need to
enclose the pattern matching it in
(..) so that they get captured.

Categories