logi sisse meist KKK

Oleks vaja täiendada MiniBB foorumi mootorit nii, et [code]...[/code] elementide vahelist teksti näidataks veebilehel sellisena nagu see elementide vahel redaktoris välja näeb. Foorumi PHP-mootoris tehakse kõik asendused PCRE (Perli regulaaravaldiste) abil. Siin on kood, mida praegu kasutan:

<?php
$pattern=$replacement=array();
$pattern[]="/\[code\](.*?)\[(.+?)\[\/code\]/i";  // alustav sulg "["
$replacement[]='[code]\\1&#91;\\2[/code]';
$pattern[]='/\[code\](.+?)\](.*?)\[\/code\]/i';  // lõpetav sulg "]"
$replacement[]='[code]\\1&#93;\\2[/code]';
// järgnevad muud bbCode asendused

$msg="[code][b]test1[/b][i]test2[/i][/code]";
// see asendus tehakse kõige lõpus
$msg=preg_replace($pattern,$replacement,$msg);
echo $msg;
?>

Asendus peaks asendama alustavad ja lõpetavad nurksulud [ ] vastvate HTML koodidega &#91 ja &#93, et varjata neid edasiste asenduste eest, kuid tundub, et asendus tehakse stringis vaid esimese sulu puhul. Kuidas ma modifitseeriksin neid avaldisi, et asendataks kõik leitud juhud? Tulemus peaks olema selline:

[code]&#91;b&#93;test1&#91;b&#93;&#91;i&#93;test2&#91;/i&#93;[/code]

praegune asendus aga on selline:

[code]&#91;b&#93;test1[/b][i]test2[/i][/code]

küsitud Dec 02 '09 at 21:40

Teet's gravatar image

Teet
792410

edited Dec 02 '09 at 21:45


 <?php

    function brquote($x) {
            $pattern=$replacement=array();
            $pattern[]="/\[/si";
            $replacement[]='&#91;';
            $pattern[]="/\]/si";
            $replacement[]='&#93;';

            return preg_replace($pattern,$replacement,$x);
    }

    $pattern=$replacement=array();
    $pattern[]="/\[code\](.+?)\[\/code\]/sie";
    $replacement[]="'[code]'.brquote('\\1').'[/code]'";
    // järgnevad muud bbCode asendused 

    $msg="[code][b]test1[/b][i]test2[/i][/code]";
    // see asendus tehakse kõige lõpus
    $msg=preg_replace($pattern,$replacement,$msg);
    echo $msg;
    ?>
link

vastatud Dec 02 '09 at 23:34

sigamozart's gravatar image

sigamozart
2994

edited Dec 03 '09 at 20:54

Elegantne lahendus. Ning uurinud PHP manuaali /e modifikaatori kohta ei näe ma ka mingit turvaprobleemi.

(Dec 03 '09 at 13:20) Rene Saarsoo ♦♦

Proovisin seda lahendust, kuid selgus järgmine häda: reavahetusi sisaldavad tekstid ei läbi seda koodi.

echo preg_match("/[code](.+?)[/code]/i","[code][b]test[/b]n[i]test2[/i][/code]");

väljastab 0.

Samas echo preg_match("/[code](.+?)[/code]/i","[code][b]test[/b][i]test2[/i][/code]"); väljastab 1.

Proovisin erinevaid võimalusi, kuid ei leidnud lahendust.

(Dec 03 '09 at 20:21) Teet

Proovi modifikaatori /s lisamist, ehk siis: /\[code\](.+?)\[\/code\]/es Vaata ka: http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

(Dec 03 '09 at 20:35) Rene Saarsoo ♦♦
1

See töötab hästi! Tänud kõigile, see on tõesti PRO foorum.

(Dec 03 '09 at 21:07) Teet

Jah, Su praegune kood asendab ainult esimest nurksulgu kummastki sordist iga [code]...[/code] jupi sees. See on sellepärast, et see kood otsib [code]...[/code] juppe, mille vahel vähemalt üks nurksulg leidub ning milles pesitsevale nurksulule vähemalt üks märk järgneb, jagab [code]...[/code] jupi sisu esimese nurksulu kohalt kaheks ja genereerib iga [code]...[/code] jupi jaoks väljundi, mis koosneb esimesest osast, vasaku nurksulu asendusest ja teisest osast. Regulaaravaldise küljest: (.*?)[(.+?) matchib märgid kuni vasaku nurksuluni $1 sisse -- kuna matchimine on helde, ei saa $1 kunagi nurksulgu sisaldada -- ning esimesele vasakule nurksulule järgnevad märgid $2 sisse -- need märgid võivad ka teisi vasakuid nurksulge sisaldada. Pluss teise punkti järel tähendab nõudmist, et nurksulule peab vähemalt üks märk järgnema; selles kontekstis on see vist viga.

Kui Sa tahad [code]...[/code] juppides kõiki nurksulge asendada, pead nood jupid eraldi asendusmehhanismist läbi laskma. Üht viisi on sigamozart juba demonud; kuna see sõltub täitmisajal stringina genereeritud koodi interpreteerimisest, mis minul veebirakenduste kontekstis turvakarvad turri ajab, räägin nüüd teisest võimalikust lahendusest.

Alustame inimsõbralikus keeles kirjutatud pseudokoodist.

sub teetquote ($) {
    my @parts = split /(\[code])(.*?)(\[\/code])/s, $_[0], -1;
    # Nüüd on @parts'is sisendstringi tükid niimoodi, et nende konkateneerimisel
    # saame sisendstringi tagasi, kusjuures esialgsete [code]...[/code] juppide
    # sisu on @parts'i positsioonidel, mille järjekorranumbri neljaga jagamise
    # jääk on 2.
    for (my $i = 2; $i < @parts; $i += 4) {
        $parts[$i] =~ s/([\[\]])/'&#'.ord($1).';'/ge;
    }
    return join '', @parts;
}

Perli split'il on omadus lõikemallis sätestatud grupid, if any, kenasti tagastatavasse listi paigutada. Kui me teame, kui palju neid tükke igas lõikekohas on, saame genereeritud listist hõlpsasti õiged tükid välja valida.

Nüüd võtame sõnaraamatu ja tõlgime selle pseudokoodi PHP'sse.

function teetquote ($s) {
    $parts = preg_split('/(\\[code])(.*?)(\\[\\/code])/s', $s,
        -1, PREG_SPLIT_DELIM_CAPTURE);

    for ($i = 2; $i < count($parts); $i += 4) {
        $parts[$i] =
            str_replace('[', '&#91;',
                str_replace(']', '&#93;',
                    $parts[$i]));
    }

    return implode($parts);
}

Parandus: ülalmainitud /s on ka selles lahenduses puudu. Lisatud.

link

vastatud Dec 03 '09 at 11:42

dig's gravatar image

dig
17415

edited Dec 03 '09 at 20:52

1

Esimest korda näen, et keegi nimetab Perli inimsõbralikuks pseudokoodiks :)

(Dec 03 '09 at 13:11) Rene Saarsoo ♦♦

Konteksti küsimus. ;-)

(Dec 03 '09 at 20:48) dig

Ma ei saa hästi aru, kuidas siinset pakutud funktsiooni praktikas kasutada, sest sisendtekstile rakendamist ei ole siin näidatud.

Mõtlesin ka välja oma lahenduse: kuna mul on $msg väärtus käes enne $pattern ja $replacement-massiivi kasvatamist, saan sellele stringile rakendada sulge avaldavaid regulaaravaldisi nii kaua, kui nende "match" tõene on, ning lasen seejärel originaalkoodil $msg-muutujat edasi töödelda. Rohmakas, aga turvalekketa.

(Dec 03 '09 at 21:16) Teet
1

Võib-olla ei saa ma murest õigesti aru, aga mispärast $msg = teetquote($msg); seda ei lahenda?

(Dec 03 '09 at 23:48) dig

Puust ette ja punaseks, aitäh.

(Dec 04 '09 at 22:56) Teet
Sinu vastus
lülita eelvaade

Jälgi seda küsimust

By Email:

Pärast sisselogimist saad tellida muudatuse teavitusi siit

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *kaldkiri* või __kaldkiri__
  • **paks kiri** või __paks kiri__
  • link:[tekst](http://url.com/ "pealkiri")
  • pilt?![alt tekst](/path/img.jpg "pealkiri")
  • nummerdatud nimekiri: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • põhilised HTML märgendid on samuti toetatud

Pinu tööpakkumised

kõik pakkumised »

Küsimuse sildid:

×22
×6

küsitud: Dec 02 '09 at 21:40

nähtud: 2,100 korda

viimati uuendatud: Dec 03 '09 at 20:54

Litsents: Creative Commons Attribution License | Kontakt: info@pinu.ee