Przetwarzanie tekstu -> wyłuskiwanie fragmentów

0

Dzień dobry.

Potrzebuję przetworzyć tekst w taki sposób, aby wyłuskać z niego pewne elementy. Mianowicie, mam stringa, np. takiego:

abc[math]x^2 + 4 > 0[/math],
[math][b]Kasia[/b] 2 * 2 * 2 = 8[/math]

Chodzi o to, by wyciągnąć wszystkie dane spomiędzy znaczników [math] i [/math], pod warunkiem, że nie ma w nich innych znaczników, takich jak:
$tags = ["b", "i", "u", "quote", "code", "list", "img", "url", "flash", "size", "color"];

Dla fragmentu powyżej, chcę wyłuskać tylko x^2 + 4 > 0

Nie umiem napisać RegExpa, próbuję to ogarnąć przez przetwarzanie znak po znaku. Może macie pomysł jak to ugryźć? :/

M.

0

A to chodzi o to, żeby tam nie było konkretnie tych 11 znaczników [b] ... [color] czy w ogóle żadnych znaczników wewnątrz []?

0

Tylko te. Ale już mam:

<?php
    function getOpenPos($txt)
    {
        $temp = [];
        $pos = strpos($txt, "[math]", 0);
        
        while ($pos)
        {
            array_push($temp, $pos);
            $pos = strpos($txt, "[math]", $pos + 1);
        }
        
        return $temp;
    }
    
    function getClosPos($txt)
    {
        $temp = [];
        $pos = strpos($txt, "[/math]", 0);
        
        while ($pos)
        {
            array_push($temp, $pos);
            $pos = strpos($txt, "[/math]", $pos + 1);
        }
        
        return $temp;
    }
    
    function checkPossProgress($arr)
    {
        $cnt = count($arr);
        
        for ($i = 0; $i < $cnt; $i++)
            if ($arr[$i][0] > $arr[$i][1])
                return false;
        
        return true;
    }
    
    function removeTags(&$arr)
    {
        $cnt = count($arr);
        
        for ($i = 0; $i < $cnt; $i++)
            $arr[$i][0] += 6;
    }
    
    function combinePos($txt)
    {
        $opened = getOpenPos($txt);
        $closed = getClosPos($txt);
        $combined = [];
        
        if ((count($opened) == count($closed)) and (count($opened) > 0))
        {
            $cnt = count($opened);
            
            for ($i = 0; $i < $cnt; $i++)
                array_push($combined, [$opened[$i], $closed[$i]]);
        }
        
        if (checkPossProgress($combined) == false)
            return ["error"];
        
        removeTags($combined);
        
        return $combined;
    }
    
    function checkForOtherTags($arr)
    {
        $tags   = ["[b]", "[i]", "[u]", "[quote", "[code]", "[list]", "[list=", "[img]", "[url]", "[url=", "[flash=", "[size=", "[color=",
                   "[/b]", "[/i]", "[/u]", "[/quote", "[/code]", "[/list]", "[/img]", "[/url]", "[/flash]", "[/size]", "[/color]"];
        $cnt    = count($arr);
        $cnt2   = count($tags);
        
        for ($i = 0; $i < $cnt; $i++)
            for ($j = 0; $j < $cnt2; $j++)
                if ((strpos($arr[$i], $tags[$j]) !== FALSE) or (strpos($arr[$i], $tags[$j]) !== FALSE))
                    return true;
        
        return false;
    }
    
    function extractContent($txt)
    {
        $poss = combinePos($txt);
        $arr = [];
        $cnt = count($poss);
        
        for ($i = 0; $i < $cnt; $i++)
            array_push($arr, substr($txt, $poss[$i][0], $poss[$i][1] - $poss[$i][0]));
        
        if (checkForOtherTags($arr) == true)
            return ["error"];
        
        return $arr;
    }
    
    $text = "abc[math][b]x^2+4[/math][math]2*4=8[/math]";
    
    echo json_encode(extractContent($text));
?>
0

Dałoby się to pewnie 1-2 regexami ogarnąć, ale skoro już napisałeś i działa, to ok :)

1

Pierwsze, zasadnicze pytanie, czemu tak się uparłeś na ten bbCode? Masz jakiś szereg już istniejącego contentu który to wykorzystuje, i nie możesz tego zmienić na nic innego?

Bo jeżeli nie, i tworzysz coś swojego, to zrób sobie przysługę i porzuć to. Takiej składni już się nie używa od bardzo dawna. Może mógłbyś po prostu skorzystać z XML? Parserów do XML'a jest masa, i mógłbyś z łatwością ograniczyć uzywanie ich tylko do tagów <math></math> (czy jakich tam chcesz).

Jeśli już koniecznie, ale to koniecznie chcesz ten bbcode (co szczerze odradzam), to tutaj jest biblioteka która to umie: http://christian-seiler.de/projekte/php/bbcode/index_en.html

Tutaj jest też snippet, który parsuje proste przypadki: https://gist.github.com/afsalrahim/bc8caf497a4b54c5d75d

Ale błagam, weź zmień zdanie. Po co Ci ten BBcode, tylko sobie robisz szkodę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1