0

Ok, so i have a string like this

$sText = '[post:1]Some test here......[/post]';

now i want to extract the text within this that is "Some test here......" and i also want the number "1" next inside the bracket [post:1]. I have tried searching for a solution but couldn't find a good one yet.

I tried to get the text inside the brackets with this

preg_match_all('/\[(.*?)\]/', $sText, $out);

and it gives me this

Array
(
    [0] => Array
        (
            [0] => [post:1]
            [1] => [/post]
        )
    [1] => Array
        (
            [0] => post:1
            [1] => /post
        )
)

I can get the number from that using explode or by any other means then i could probably get the text by using regex to remove the brackets but that sounds like too much regex. Is there any better solution/idea for this? Well i am not good with regex.

2
  • BBCode? php.net/manual/en/book.bbcode.php Commented Nov 20, 2013 at 16:11
  • Can't use that as i only need it for a very specific case and that requires installation and this product is for other users. Commented Nov 20, 2013 at 16:25

2 Answers 2

1

Try this:

preg_match_all('~\[(?<tag>\w+):(?<nbr>\d+)](?<content>(?>[^[]++|\[(?!/\1]))+)\[/\1]~',
               $sText, $matches, PREG_SET_ORDER);

foreach($matches as $match) {
    echo '<br/>' . $match['tag'] . "\t" . $match['nbr'] . "\t" . $match['content'];
}

pattern detail:

~                     # pattern delimiter
\[                    # literal [ (must be escaped)
(?<tag>\w+)           # named capture with the tag name (alphanumeric + _)
:                     # literal :
(?<nbr>\d+)           # named capture for the number
]                     # literal ]
(?<content>           # named capture for the content inside tags
    (?>               # open an atomic group
        [^[]++        # all characters that are not a [ one or more times
      |               # OR
        \[(?!/\1])    # literal [ not follow by "/tagname]" 
    )+                # close the atomic group, repeat it 1 one more times
)                     # close the named capture: content
\[/                   # literal [/
\1                    # reference to the capturing group 1 (tagname)
]                     # literal ]
~                     # pattern delimiter
Sign up to request clarification or add additional context in comments.

Comments

1

I'm thinking about something like this

$sText = '[post:1]Some test here......[/post]';

$pattern =  '/\:(\d+)\](.*?)\[/';

preg_match_all($pattern, $sText, $a);

var_dump($a);

which returns

array (size=3)
  0 => 
      array (size=1)
          0 => string ':1]Some test here......[' (length=24)
  1 => 
      array (size=1)
          0 => string '1' (length=1)
  2 => 
      array (size=1)
          0 => string 'Some test here......' (length=20)

1 Comment

Thanks for your answer but i am using the other one for now. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.