How do I find multiple matches with one regular expression?
I've got the following string:
response: id="1" message="whatever" attribute="none" world="hello"
The order of the attributes is random. There might be any number of other attributes.
开发者_开发知识库Is there a way to get the id, message and world attribute in one regular expression instead of applying the following three one after another?
/ message="(.*?)"/
/ world="(.*?)"/
/ id="(.*?)"/
You can achieve this by using three positive lookahead assertions with .*
at the front of them:
<?php
$re = '/(?=.* message="(.*?)")(?=.* world="(.*?)")(?=.* id="(.*?)")/';
$string = '<response id="1" message="whatever" attribute="none" world="hello" />';
preg_match($re, $string, $matches);
var_dump($matches);
Output:
array(4) {
[0]=>
string(0) ""
[1]=>
string(8) "whatever"
[2]=>
string(5) "hello"
[3]=>
string(1) "1"
}
Of course, this pattern will fail if any of those 3 parameters are missing (which might be helpful to you too...). If you want them to be optional, you can further wrap the inside of the lookahead into a non-capture group and make it optional (?:....)?
(this example makes the "world" parameter optional)
/(?=.* message="(.*?)")(?=(?:.* world="(.*?)")?)(?=.* id="(.*?)")/
If you are using preg_match
, then there's an optional third argument which will store all the regular expression groups (anything inside parentheses, basically) as well as the full match.
So use the whole thing as one regular expression and then the 2nd, 3rd, and 4th elements will be the message
, world
, and id
respectively (the 1st will be the whole string that matched.
I'm not a regex guy, so this might be wrong. If it is, don't downvote =) just let me know and I'll delete it! :-D
Could you or the phrases together and match that?
/ (message|world|id)="(.*?)"/
The below is the best one I can come up with. It should capture the actual attributes matched at each point, their values and also allow anything other inbetween. It's not strictly correct though, and you would do well to use a "real" parser.
/((message|attribute|world)="([^"]*)").*?((message|attribute|world)="([^"]*)").*?((?:message|attribute|world)="([^"]*)")/
精彩评论