I need to parce a string like that: "{data type="subject"} using regular expressions in PHP.
I've got this:
$template = '/{([\w]+)\s([\w]+)="([\w]+)"}/';
but nothing happens.
Can anyone help me with that?
Everything looks fine.
Your pattern:
<?php
$s = '{data type="subject"}';
$template = '/{([\w]+)\s([\w]+)="([\w]+)"}/';
preg_match($template, $s, $matches);
var_dump($matches);
Result is:
array(4) {
[0] =>
string(21) "{data type="subject"}"
[1] =>
string(4) "data"
[2] =>
string(4) "type"
[3] =>
string(7) "subject"
}
Show your full example, please.
Curly braces must be escaped. Try something like this :
'/\{(\w+)\s(\w+)="(\w+)"\}/'
Edit : changed a little mistake. I've tried it, it works fine.
Related
I have text:
<b>Title1:</b><br/><b>Title2:</b> Value1<br/><b>Title3:</b> Value2<br/><b>Title4:</b> Value3<br/>Value4<b>Title5:</b> Value5<br/>
What regex to get:
[0] => <b>Title1:</b><br/>
[1] => <b>Title2:</b> Value1<br/>
[2] => <b>Title3:</b> Value2<br/>
[3] => <b>Title4:</b> Value3<br/>Value4
[4] => <b>Title5:</b> Value5<br/>
My variant not working:
<b>(.*?)</b>(.*?)
You can use preg_split() with a lookahead:
<?php
$split = preg_split( '/(?=<b>Title\d+:)/', '<b>Title1:</b><br/><b>Title2:</b> Value1<br/><b>Title3:</b> Value2<br/><b>Title4:</b> Value3<br/>Value4<b>Title5:</b> Value5<br/>' );
array_shift( $split );
var_dump( $split );
Output:
array(5) {
[0]=>
string(19) "<b>Title1:</b><br/>"
[1]=>
string(26) "<b>Title2:</b> Value1<br/>"
[2]=>
string(26) "<b>Title3:</b> Value2<br/>"
[3]=>
string(32) "<b>Title4:</b> Value3<br/>Value4"
[4]=>
string(26) "<b>Title5:</b> Value5<br/>"
}
Your regex was close, you need:
<b>(.*?)<\/b>(.*?)(?=<b>|$)
https://regex101.com/r/dk67IK/1
A resource like this can be very useful in troubleshooting regex: https://regex101.com/
Looks like you are missing an escape character in <b>(.*?)</b>(.*?)
<b>(.*?)<\/b>(.*?) should stop an error from being thrown for that current regex and get you close to the result, you'll need to work with it a bit more to get the exact results you want though.
<b>(.*?)<\/b>(.*?)<br\/> should be a bit closer I think as it looks like you want to include the break tags.
I have several texts with custom macro tags in it. I want to parse the content of these tags but I'd like to treat the ones with parameters in it differently.
I need to construct valid URLs out of these bracket contents.
Example:
This is my text:
{gallery}events/2016-02-18-Sunny-Sport-Day,single=IMG_0336.jpg,salign=left{/gallery}
Hey there! We had a great day with a tough but funny competition. Our
team had a great race and was able to finish in second place.
{gallery}events/2016-02-18-Sunny-Sport-Day{/gallery}
{gallery}team/members{/gallery}
So I need to extract the path parts of the string between the {gallery} tags but I don't want to match those with parameters such as "single=IMG_0336.jpg,salign=left" because these are treated separately.
I need something which does the following:
{gallery}events/2016-02-18-Sunny-Sport-Day,single=IMG_0336.jpg,salign=left{/gallery}
becomes
first output: events/2016-02-18-Sunny-Sport-Day
second output: IMG_0336.jpg
and
{gallery}events/2016-02-18-Sunny-Sport-Day{/gallery}
becomes
events/2016-02-18-Sunny-Sport-Day
Tried the following regex:
/\{gallery\}(.*?)(?!single=)\{\/gallery\}/
But it allways matches the whole string including the single parameter.
To get the content of the single parameter I tried the following:
/,single=(.*?),/
This works fine for the single paramter only but I don't know how to get everything together.
Conclusion:
In a PHP environment I would like to have as output two arrays. The first consists only of the folders:
events/2016-02-18-Sunny-Sport-Day
team/members
and a second array which consists of the single file paths:
events/2016-02-18-Sunny-Sport-Dayist/IMG_0336.jpg
This method will extract your desired substrings and prepare the output data as you have requested: Pattern Demo
PHP Code: (Demo)
$str="{gallery}events/2016-02-18-Sunny-Sport-Day,single=IMG_0336.jpg,salign=left{/gallery}
Hey there! We had a great day with a tough but funny competition. Our team had a great race and was able to finish in second place.
{gallery}events/2016-02-18-Sunny-Sport-Day{/gallery}
{gallery}team/members{/gallery}";
preg_match_all('#\{gallery\}([^,]*?)(?:,single=([^,{]+).*?)?\{/gallery\}#',$str,$out);
// Matches array:
var_export($out);
echo "\n\n---\n\n";
// Folders only array:
var_export(array_filter(array_slice($out,1)[0],'strlen'));
echo "\n\n---\n\n";
// Path + Image files array:
foreach($out[2] as $i=>$v){
if($v){
$result[]="{$out[1][$i]}/$v";
}
}
var_export($result);\
Output:
array (
0 =>
array (
0 => '{gallery}events/2016-02-18-Sunny-Sport-Day,single=IMG_0336.jpg,salign=left{/gallery}',
1 => '{gallery}events/2016-02-18-Sunny-Sport-Day{/gallery}',
2 => '{gallery}team/members{/gallery}',
),
1 =>
array (
0 => 'events/2016-02-18-Sunny-Sport-Day',
1 => 'events/2016-02-18-Sunny-Sport-Day',
2 => 'team/members',
),
2 =>
array (
0 => 'IMG_0336.jpg',
1 => '',
2 => '',
),
)
---
// Folders only array:
array (
0 => 'events/2016-02-18-Sunny-Sport-Day',
1 => 'events/2016-02-18-Sunny-Sport-Day',
2 => 'team/members',
)
---
// Path + Image files array:
array (
0 => 'events/2016-02-18-Sunny-Sport-Day/IMG_0336.jpg',
)
something like this?
<?php
$str=getstr();
preg_match_all('/\{gallery\}(.*?)\{\/gallery\}/u',$str,$matches);
$parsed=[];
foreach($matches[1] as $match){
$tmp=[];
$match=explode(',',$match);
foreach($match as $tmp2){
$tmp2=explode("=",$tmp2);
assert(count($tmp2)<=2);
if(count($tmp2)>1){
$tmp[$tmp2[0]]=$tmp2[1];
}else{
$tmp[]=$tmp2[0];
}
}
$parsed[]=$tmp;
}
var_dump($parsed);
function getstr():string{
$str=<<<'STR'
{gallery}events/2016-02-18-Sunny-Sport-Day,single=IMG_0336.jpg,salign=left{/gallery}
Hey there! We had a great day with a tough but funny competition. Our team had a great race and was able to finish in second place.
{gallery}events/2016-02-18-Sunny-Sport-Day{/gallery}
{gallery}team/members{/gallery}
STR;
return $str;
}
$parsed[0][0] contains events/2016-02-18-Sunny-Sport-Day ,
$parsed [0]["single"] contains IMG_0336.jpg
$parsed [0]["salign"] contains left
$parsed[1][0] contains events/2016-02-18-Sunny-Sport-Day
$parsed[2][0] contains team/members
full output of the var_dump is
array(3) {
[0]=>
array(3) {
[0]=>
string(33) "events/2016-02-18-Sunny-Sport-Day"
["single"]=>
string(12) "IMG_0336.jpg"
["salign"]=>
string(4) "left"
}
[1]=>
array(1) {
[0]=>
string(33) "events/2016-02-18-Sunny-Sport-Day"
}
[2]=>
array(1) {
[0]=>
string(12) "team/members"
}
}
i have data in my mysql database "Service,House Worker" (without ""), when i access my data from the database i found (Service,House Worker) as it is, when i try to convert with (var_dump(explode(',',($CheckBoxAnswer)));) it then its return following :
array(1) { [0]=> string(26) "Service,House Worker" }
but i want something similar:
array(1)
(
[0] => string(7) "Service"
[1] => string(13) "House Worker"
)
$CheckBoxAnswer is contain data i pulled from mysql.
i tried with var_dump(explode(',',($CheckBoxAnswer)));
but its not working
Try this:
var_dump(explode(',',($CheckBoxAnswer[0])));
You are tring to explode an array into an another array. You need to specify the string instead.
First you need to trim $CheckBoxAnswer
Because by using var_dump giving string length 26 instead of 20
Then after use string replace
str_replace('/','',$CheckBoxAnswer);
After that try to use var_dump(explode(',',($CheckBoxAnswer)));
The code:
$pattern = '~(/(?P<lang>en|ru))?/foo(/(?P<bar>bar))?~';
preg_match($pattern, '/foo', $matches);
var_dump($matches);
/*output:
array(1) {
[0] =>
string(4) "/foo"
}*/
preg_match($pattern, '/foo/bar', $matches);
var_dump($matches);
/*output:
array(7) {
[0] =>
string(8) "/foo/bar"
[1] =>
string(0) ""
'lang' =>
string(0) ""
[2] =>
string(0) ""
[3] =>
string(4) "/bar"
'bar' =>
string(3) "bar"
[4] =>
string(3) "bar"
}*/
The question: why the hell does it capture <lang> in the second preg_match call and how do I fix it?
P.S. I tried this regex on https://www.regex101.com and there it captures correctly, but on my machine with PHP7, it does not. I get the feeling that regex101 filters the output.
As others have said, that's simply how regex works. It's fairly universal to regexes, as far as I know. It even has parallels in programming in general, such as how Java requires a String returning function to return a String (unless it throws an error).
In PHP, use array_filter on $matches to remove empty entries.
Also, I suggest using non-capturing groups (?:) to cut the clutter:
(?:/(?P<lang>en|ru))?/foo(?:/(?P<bar>bar))?
Or split it into 2 regexes: (?:/(?P<lang>en|ru)) and /foo(?:/(?P<bar>bar)).
I'm having problems matching the[*] which is sometimes there and sometimes not. Anyone have suggestions?
$name = 'hello $this->row[today1][] dfh fgh df $this->row[test1] ,how good $this->row[test2][] is $this->row[today2][*] is monday';
echo $name."\n";
preg_match_all( '/\$this->row[.*?][*]/', $name, $match );
var_dump( $match );
output:
hello $this->row[test] ,how good $this->row[test2] is $this->row[today][*] is monday
array (
0 =>
array (
0 => '$this->row[today1][*]',
1 => '$this->row[test1] ,how good $this->row[test2][*]',
2 => '$this->row[today2][*]',
),
)
Now the [0][1] match takes on too much because it is matching until the next '[]' instead of ending at '$this->row[test]' . I'm guessing the [*]/ adds a wildcard. Somehow need to check if the next character is [ before matching to []. Anyone?
Thanks
[, ] and * are special meta characters in regex and you need to escape them. Also you need to make last [] optional as per your question.
Following these suggestions following should work:
$name = 'hello $this->row[today1][] dfh fgh df $this->row[test1] ,how good $this->row[test2][] is $this->row[today2][*] is monday';
echo $name."\n";
preg_match_all( '/\$this->row\[.*?\](?:\[.*?\])?/', $name, $match );
var_dump( $match );
OUTPUT:
array(1) {
[0]=>
array(4) {
[0]=>
string(20) "$this->row[today1][]"
[1]=>
string(17) "$this->row[test1]"
[2]=>
string(19) "$this->row[test2][]"
[3]=>
string(21) "$this->row[today2][*]"
}
}