extracting data between [ ] with preg_match php - php

i try to extract only the number beetween the [] from my response textfile:
$res1 = "MESSAGE_RESOURCE_CREATED Resource [realestate] with id [75739528] has been created.";
i use this code
$regex = '/\[(.*)\]/s';
preg_match($regex, $res1, $matches_arr);
echo $matches_arr[1];
my result is:
realestate] with id [75742084
Can someone help me ?

Use this:
$regex = '~\[\K\d+~';
if (preg_match($regex, $res1 , $m)) {
$thematch = $m[0];
// matches 75739528
}
See the match in the Regex Demo.
Explanation
\[ matches the opening bracket
The \K tells the engine to drop what was matched so far from the final match it returns
\d+ matches one or more digits

I assume you want to match what's inside the brackets, which means that you must match everything but a closing bracket:
/\[([^]]+)\]/g
DEMO HERE
Omit the g-flag in preg_match():
$regex = '/\[([^]]+)\]/';
preg_match($regex, $res1, $matches_arr);
echo $matches_arr[1]; //will output realestate
echo $matches_arr[2]; //will output 75739528

Your regex would be,
(?<=\[)\d+(?=\])
DEMO
PHP code would be,
$regex = '~(?<=\[)\d+(?=\])~';
preg_match($regex, $res1, $matches_arr);
echo $matches_arr[0];
Output:
75739528

Related

How do I get number from this format:,[[5,["95",1,"#ffffff"]]]], using regex

I have a string like this:
",[[3,"bus.png",null,"Bus",[["https://maps.gstatic.com/mapfiles/transit/iw2/b/bus.png",0,[15,15],null,0]]]],[[null,null,null,null,"0x31da18325b415901:0xeb661015c651c24a",[[5,["48",1,"#ffffff"]]]],[null,null,null,null,"0x31da19f34e04d59b:0x5758ef6990938b",[[5,["61",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a5b8b75c379:0x6a13e189555f9fab",[[5,["95",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a16ea23bf95:0xd7c90f15535c2b9f",[[5,["106",1,"#ffffff"]]]],[null,null,null,null,"0x31da10a7613d616f:0xf1f61ffeac2ea8a4",[[5,["970",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a0bd6262d0b:0xfbd5d2bfd7a1252",[[5,["NR8",1,"#ffffff"]]]]],null,0,"5"]]],["http://www
I need to get all the numbers: "48, 61,95,106,970,NR8"; so basically, need to process this format :"48, 61,95,106,970,NR8"
I tried:
function get_numbers_from($input) {
$matches = preg_match_all('(\[\"[]a-zA-Z0-9]*?\"\,\d*?\,\".*?\"\])', $input);
foreach($matches[1] as $key => $match) {
array_push($numbers, explode(',', $match)[0]);
}
return $numbers;
}
But seems it shows: Invalid argument supplied for foreach()
How to correct it?
Check the manual for preg_match_all(), the function returns a boolean. And you use the third parameter for the matches.
Also you can change your regex to this one:
\[\[\d+,\[\"(\w+)\",\d+,"#[\da-fA-F]+"]]]]
To get the number directly from it without explode(), e.g.
function get_numbers_from($input) {
preg_match_all('/\[\[\d+,\[\"(\w+)\",\d+,"#[\da-fA-F]+"]]]]/', $input, $matches);
return $matches[1];
}
You can use
'~\["([A-Z]*\d+)"~'
See the regex demo and the IDEONE demo
$re = '~\["([A-Z]*\d+)"~';
$str = "\",[[3,\"bus.png\",null,\"Bus\",[[\"https://maps.gstatic.com/mapfiles/transit/iw2/b/bus.png\",0,[15,15],null,0]]]],[[null,null,null,null,\"0x31da18325b415901:0xeb661015c651c24a\",[[5,[\"48\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da19f34e04d59b:0x5758ef6990938b\",[[5,[\"61\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a5b8b75c379:0x6a13e189555f9fab\",[[5,[\"95\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a16ea23bf95:0xd7c90f15535c2b9f\",[[5,[\"106\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da10a7613d616f:0xf1f61ffeac2ea8a4\",[[5,[\"970\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a0bd6262d0b:0xfbd5d2bfd7a1252\",[[5,[\"NR8\",1,\"#ffffff\"]]]]],null,0,\"5\"]]],[\"http://www\n48, 61,95,106,970,NR8";
preg_match_all($re, $str, $matches);
print_r($matches[1]);
The pattern matches:
\[ - a [
" - a quote
([A-Z]*\d+) - Group 1: any uppercase ASCII letter, 0 or more times, followed with 1 or more digits
" - a quote
The value you need is located inside the $matches[1] variable. It holds all the values captured with the parenthesized subpattern (Group 1).

Why is my regex rejecting apostrophes?

I'm making a regex which should match everything like that : [[First example]] or [[I'm an example]].
Unfortunately, it doesn't match [[I'm an example]] because of the apostrophe.
Here it is :
preg_replace_callback('/\[\[([^?"`*%#\\\\:<>]+)\]\]/iU', ...)
Simple apostrophes (') are allowed so I really do not understand why it doesn't work.
Any ideas ?
EDIT : Here is what's happening before I'm using this regex
// This match something [[[like this]]]
$contents = preg_replace_callback('/\[\[\[(.+)\]\]\]/isU',function($matches) {
return '<blockquote>'.$matches[1].'</blockquote>';
}, $contents);
// This match something [[like that]] but doesn't work with apostrophe/quote when
// the first preg_replace_callback has done his job
$contents = preg_replace_callback('/\[\[([^?"`*%#\\\\:<>]+)\]\]/iU', ..., $contents);
try this:
$string = '[[First example]]';
$pattern = '/\[\[(.*?)\]\]/';
preg_match ( $pattern, $string, $matchs );
var_dump ( $matchs );
You can use this regex:
\[\[.*?]]
Working demo
Php code
$re = '/\[\[.*?]]/';
$str = "not match this but [[Match this example]] and not this";
preg_match_all($re, $str, $matches);
Btw, if you want to capture the content within brackets you have to use capturing groups:
\[\[(.*?)]]

php get grouped values in Regex

i am using php Regular expressions but i can't retrieve values that i group using ()
this is my input
<img src="http://www.example.com/image.jpg" title="title" />
i need only src value , this is my regex '"<img src=\"(.*?)\".*?\/>"'
if i can retrieve First group just like java patterns my problem is sloved
preg_match_all('"<img src=\"(.*?)\".*?\/>"', $source, $re);
print_r($re);
and it return full image tag like this <img src="http://www.example.com/image.jpg" title="title" />
To match a single string, preg_match function is enough. You don't need to go for preg_matchall function. If you want to match more number of strings then you could use preg_matchall function. And also first try to match the exact string through the pattern rather than to go for grouping. If it's impossible to match a particular string then go for grouping.
In the below, matching the exact value of src attribute is done.
You could get the value of src in two ways,
1. positive lookbehind
Regex:
(?<=src=\")[^\"]*
PHP code:(Through match_all)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~(?<=src=\")[^\"]*~';
preg_match_all($regex, $string, $matches);
print_r($matches);
?>
PHP code:(Through match)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~(?<=src=\")[^\"]*~';
if (preg_match($regex, $string, $m)) {
$yourmatch = $m[0];
echo $yourmatch;
}
?> //=> http://www.example.com/image.jpg
Explanation:
(?<=src=\") Positive look-behind is used here. So the regex engine puts the match marker just after to the src=".
[^\"]* Now it starts matching any character zero or more times but not of ". When it finds a ", it stops matching characters.
2. Using \K
Regex:
src=\"\K[^\"]*
PHP code (through match)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~src=\"\K[^\"]*~';
if (preg_match($regex, $string, $m)) {
$yourmatch = $m[0];
echo $yourmatch;
}
?> //=> http://www.example.com/image.jpg
Explanation:
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match.
src=\"\K So it discards the previously matched src=".
[^\"]* Matches any character zero or more times but not of "
You're using preg_match_all so that you need to pass index as well, use print_r($re[1]); to get results.
I Got It Accidently !
we can Code Like this for first Grouped
print_r($re[1]);

PHP Regex to match the last occurrence of a string

My string is $text1 = 'A373R12345'
I want to find last none digital number occurrence of this string.
So I use this regular expression ^(.*)[^0-9]([^-]*)
Then I got this result:
1.A373
2.12345
But my expected result is:
1.A373R
(It has 'R')
2.12345
Another example is $text1 = 'A373R+12345'
Then I got this result:
1.A373R
2.12345
But my expected result is:
1.A373R+
(It has '+')
2.12345
I want contain the last none digital number!!
Please help !! thanks!!
$text1 = 'A373R12345';
preg_match('/^(.*[^\d])(\d+)$/', $text1, $match);
echo $match[1]; // A373R
echo $match[2]; // 12345
$text1 = 'A373R+12345';
preg_match('/^(.*[^\d])(\d+)$/', $text1, $match);
echo $match[1]; // A373R+
echo $match[2]; // 12345
Explanation of regex broken down:
^ match from start of string
(.*[^\d]) match any amount of characters where the last character is not a digit
(\d+)$ match any digit character until end of string

Regex: Using capture data further in the regex

I want to parse some text that start with ":" and could be surround with parentheses to stop the match so:
"abcd:(someText)efgh" and
"abcd:someText"
will return someText.
but i have a problem to set the parentheses optionnal.
I make this but it does not works:
$reg = '#:([\\(]){0,1}([a-z]+)$1#i';
$v = 'abc:(someText)def';
var_dump(preg_match($reg,$v,$matches));
var_dump($matches);
The $1 makes it failed.
i don't know how to tell him :
If there is a "(" at the beginning, there must be ")" at the end.
You can't test if the count of something is equal to another count. It's a regex problem who can only be used with regular language (http://en.wikipedia.org/wiki/Regular_language). To achieve your goal, as you asked - and that is if there's a '(' should be a ')' -, you'll need a Context-Free Language (http://en.wikipedia.org/wiki/Context-free_language).
Anyway, you can use this regex:
'/:(\([a-z]+\)|[a-z]+)/i
To return the match of different sub-patterns in the regex to the same element of the $matches array, you can use named subpattern with the internal option J to allow duplicate names. The return element in $matches is the same as the name of the pattern:
$pattern = '~(?J:.+:\((?<text>[^)]+)\).*|.+:(?<text>.+))~';
$texts = array(
'abc:(someText)def',
'abc:someText'
);
foreach($texts as $text)
{
preg_match($pattern, $text, $matches);
echo $text, ' -> ', $matches['text'], '<br>';
}
Result:
abc:(someText)def -> someText
abc:someText -> someText
Demo
This regex will match either :word or :(word) groups 1 and 2 hold the respective results.
if (preg_match('/:([a-z]+)|\(([a-z]+)\)/i', $subject, $regs)) {
$result = ($regs[1])?$regs[1]:$regs[2];
} else {
$result = "";
}
regex: with look-behind
"(?<=:\(|:)[^()]+"
test with grep:
kent$ echo "abcd:(someText)efgh
dquote> abcd:someOtherText"|grep -Po "(?<=:\(|:)[^()]+"
someText
someOtherText
Try this
.+:\((.+)\).*|.+:(.+)
if $1 is empty there are no parentheses and $2 has your text.

Categories