Jump to content

Do Non-obligatory (optional) subpatterns exist?


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! :)

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.