简体   繁体   中英

preg_match search

<?php
$content = "
{php
    {php 1 php}
    {php 2 php}
    {php 3 php}
php}"; 

How I can get 4 strings?

First:

{php 1 php}
{php 2 php}
{php 3 php}

Second:

1

Third:

2

Four:

3

While you could easily parse such input with a simple counter, it is possible to use a recursive regex to get what you want. A simple (?) regex to validate the input would be:

^({php\s*(\d+|(?1)+)\s*php}\s*)$

(?1) is a recursive match, it tries to match the first group again, which is another {php ... php} token. We also have a capturing group between the php s to capture their content.

In your case you want to capture overlapping results (in fact, even results contained within other results). This is even less pretty, but still possible, using a look-ahead. Look-around can have capturing groups, so the pattern would be:

(?=({php\s*(\d+|(?1)+)\s*php}\s*))

The result has a two extra captured groups - blank results for the look around, and the whole token with the outer {php ... php} , but if you use PREG_PATTERN_ORDER your expected results will be on the third postion ( [2] ):

[2] => Array
(
    [0] => {php 1 php}
           {php 2 php}
           {php 3 php}
    [1] => 1
    [2] => 2
    [3] => 3
)

Here's a bit more complex example: http://ideone.com/sWWrT

Now, the mandatory word of caution. As I've said earlier, this is much more readable and maintainable with a simple depth counter, you don't really need a regex here, beyond recreational use.

$regex = preg_match_all("/({php (\d+) php})+/", $content);
$regex[0][0] == "{php 1 php}";
$regex[0][1] == "{php 2 php}";
$regex[0][2] == "{php 3 php}";
end($regex)[0] == "1";
end($regex)[1] == "2";
end($regex)[2] == "3";

Looking for something like this?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM