1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Get all bbcode tags into array.

Discussion in 'PHP' started by Thorlax402, Jan 19, 2011.

  1. #1
    Hey everyone,

    I've been trying to do something in php today and I've run into a snag. I have a string containing a series of bbcode tags like such:
    [tag1]content1[/tag1][tag2]content2 and such.[/tag2]
    Code (markup):
    I also have a function that allows me to get the content of a specified tag:
    function getTagInfo($tag, $string, $offset=0) {
    		$startTag = "[{$tag}]";
    		$endTag = "[/{$tag}]";
    		
    		if ($startPos = strpos($string, $startTag, $offset)) {
    			$startPos += strlen($startTag);
    			$endPos = strpos($string, $endTag, $startPos);
    			return substr($string, $startPos, $endPos - $startPos);
    		} else {
    			return false;
    		}
    	}
    PHP:
    My problem is that I am trying to get all the tags and put them into an array to make life a little easier for me. However, I realized I have no way of knowing how many different tags are in the string since the number of tags will vary. I was hoping to figure out a way to use some sort of pattern like "[*]" and "[/*]", but I cannot figure out a way to do so.
    SEMrush
    If anyone has any ideas then please let me know. Thanks in advance.
     
    Thorlax402, Jan 19, 2011 IP
    SEMrush
  2. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #2
    function returnTags($tag, $content) {
         $tag = preg_quote($tag, '#');
         preg_match_all("#\[{$tag}(?:=.+?)?\](.+?)\[/{$tag}\]#s", $content, $a);
         return $a;
    }
    PHP:
    That should return an array of all contents of a specific BBCode tag (each new value is the contents of an occurence of that specific BBCode tag). However word of caution this will NOT work on nested tags. (seeing your initial post & example - I believe that isn't an issue?)
     
    danx10, Jan 20, 2011 IP
    G3n3s!s likes this.
  3. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #3
    That is not an issue, however. I am not looking to get a specific tag. The function I provided above will do that in my case just fine. What I need is to get all the tags in a string into an associative array. For example, this string:
    [tag1]Some content for tag1[/tag1][tag2]Tag 2 content[/tag2]
    Code (markup):
    Would create an array as such:
    $arr["tag1"] = "Some content for tag1";
    $arr["tag2"] = "Tag 2 content";
    PHP:
    The goal of this is to try to emulate a database table structure in a .txt file with bbcode tags contained in other "[row]" tags. I was hoping to avoid creating separate methods for getting information from my makeshift tables, but it seems I might have to either do that, or create another .txt file containing information about its associated table file (column names, id counter, etc).

    However, it would be much nicer and cleaner if I could get something like this to work so if anyone has any ideas then please let me know.


    Thanks in advance.
     
    Thorlax402, Jan 20, 2011 IP
  4. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #4


    <?php
    
    $content = '[tag1]Some content for tag1[/tag1][tag2]Tag 2 content[/tag2]';
    
    preg_match_all('#\[(.+?)(?:=.+?)?\](.+?)\[/\1\]#is', $content, $matches, PREG_SET_ORDER);
    
    $arr = array();
    
    foreach ($matches as $a) {
    $arr[$a[1]] = $a[2];
    }
    
    print_r($arr);
    
    
    PHP:
     
    danx10, Jan 20, 2011 IP
  5. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #5
    Works beautifully, thank you.

    Hate to be a pain, but do you mind explaining how the pattern in preg_match_all() works? I've read the documentation a number of times and never really could figure out how to format my patterns properly.
     
    Thorlax402, Jan 21, 2011 IP
  6. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #6
    Regex is tough to learn, but once you get the hang of it - it can be very useful, I'm still learning myself.

    Before I start explaining, this is only about using regex within PHP. I've also linked all aspects which build a regex to its corresponding php.net documentation page, so you can get more info via that (if you don't understand it). The majority is written by me but some quotes are taken from php.net (such as the delimiter examples - to prevent me from reinventing the cycle).

    Here is the complete regex:

    #\[(.+?)(?:=.+?)?\](.+?)\[/\1\]#is
    Code (markup):
    1. A regex is short for regular expression. Which is a pattern usually used to select data which is generic. (Good for scraping, validating etc.).
    2. A regex (as of PHP 5) can be used with a variety of preg_ functions (most return an array of the matches and others make replacements according to the regex).
    3. All regexes open and close with a delimiter. (I'd assume this allows the PHP interpreter to distinguish wheres the regex). A delimiter can be any non-alphanumeric, non-backslash, non-whitespace character. Often used delimiters are forward slashes (/), hash signs (#) and tildes (~). In this case I've used the hash sign (#) - personal preference.
    4. Regex can have modifiers, which is/are characters(s) at the end of the regex (after the closing delimiter). These are certain/specific characters which do specific actions to the regex. Such as the i modifier makes the regex case insensitive so it will match regardless of the case (by default without this its case sensitive). In this case I've used the i and s modifiers.
    5. You can select data which you'd like to match/return by enclosing the specific pattern with parenthises/brackets (without this it would'nt be included within the returned array). Then to retrieve a specific match you'd indentify it numerically (from the order left to right).
    6. Be aware, that you'd need to escape/backslash certain characters and any characters which you used as the delimiter (I'd assume so the PHP interpreter can locate the regex) within the regex, which is why I've escaped the [ and ] characters. Luckily PHP has a function to simplify the process called preg_quote().

    The following is the regex for the opening BBCode tag:

    \[(.+?)(?:=.+?)?\]
    Code (markup):
    Is basically saying match atleast 1 character or more after the [ character up to the ] character, and optionally allow another paremeter within the BBCode:

    So it will accept:

    [quote]
    Code (markup):
    Aswell as:

    [quote="danx10"]
    Code (markup):
    The following does the "match atleast 1 character or more after the [ character up to the ] character", the + means 1 character or more, the ? means up to, and refer to point 5 as to why its wrapped within parenthises/brackets:

    (.+?)
    Code (markup):
    The following does the "optionally allow another paremeter within the BBCode", its proceded by the ? character (when its proceded; whatever is within the parenthises before it; is considered optional). The ?: after the opening parenthises just means to not match this (as the reason why its wrapped in parenthises is so the PHP interpreter can recognise what bit to make optional):

    (?:=.+?)?
    Code (markup):

    The following is the regex for the closing BBCode tag:

    \[/\1\]
    Code (markup):
    Its basically saying ensure it contains a closing BBCode tag which contains the first match (which is why \1 is used).


    Hope that helped, below is a great article/tutorial which you may find useful to learn regex.

    http://www.phpro.org/tutorials/Introduction-to-PHP-Regex.html
     
    danx10, Jan 22, 2011 IP
    hogan_h likes this.