Jump to content

Do Non-obligatory (optional) subpatterns exist?


Goldeneye

Recommended Posts

The Question

Is it possible to make a subpattern non-obligatory in the same way that you that you can make alpha-numeric characters (ex: "https?" matches both "http" and "https" non-obligatory?

 

The Reason

The reason I ask is because I'm trying to match a BB-Code tag with an optional-attribute. What I'm trying to match is <URL>( align=<left|center|right>) where the " align=..." is non-obligatory.

 

Currently I am using:

'/(\[img=(.*?)\])|(\[img=(.*?) align=(left|center|right))\]/i'

This patterns works perfectly, but in search of something (potentially) more efficient... I am trying to utilize optional-subpatterns:

Attempt 1:
'/(\[img=(.*?)(?\s(align=(left|center|right))))\]/i'

Attempt 2:
'/(\[img=(.*?)(\s(align=(left|center|right)))?\]/i'

 

So is what I'm attempting to do completely oblivious of me? I did check the PHP-Manual for some help and I came across Conditional-Subpatterns, but I Non-Obligatory Subpatterns seemed to be the way to go.

Aside from having more brackets than you appear to need you don't seen far off, something like this should suffice.

 

'#\[img=(.*?)(?: align=(left|center|right))?\]#i'

 

Of course you asked about pattern matching, whereas in this situation the trick will probably be the replacement.

Alternatively you could save yourself the horror and use pecl bbcode extension http://php.net/manual/en/book.bbcode.php or the PEAR extension http://pear.php.net/package/HTML_BBCodeParser

 

I would take that route instead but unfortunately, the server I'm using doesn't have the BBCode Extension installed. I can't install it either as it isn't my server. =\

 

Aside from having more brackets than you appear to need you don't seen far off, something like this should suffice.

 

'#\[img=(.*?)(?: align=(left|center|right))?\]#i'

 

Of course you asked about pattern matching, whereas in this situation the trick will probably be the replacement.

 

I took the Expression you provided and modified it slightly. I made the first subpattern greedy by removing the "(*?)" and replaced it with a subpattern that only matches URLs:

'#\[img=(https?://\S+)(?: align=(left|center|right))?\]#i'

Now it will work as a matching-expression.

 

I tested it:

<?php
    $str = '[img=http://google.com align=left]';
if(preg_match_all('#\[img=(https?://\S+)(?: align=(left|center|right))?\]#i', $str, $match))
	print_r($match);
else
	echo '$str was not matched!';
?>

 

With that, you should get an array:

Array
(
    [0] => Array
        (
            [0] => [img=http://google.com align=left]
        )

    [1] => Array
        (
            [0] => http://google.com
        )
    [2] => Array
        (
            [0] => left
        )

)

 

Thank you very much for your replies, cags and ignace! :)

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.