[PHP] String converteren naar kleine letters in preg*

Pagina: 1
Acties:
  • 143 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • drGoeroe
  • Registratie: Januari 2002
  • Laatst online: 04-09-2021
Ik wil het volgende bereiken;
Elke URL naar een plaatje moet geconverteerd worden naar kleine letters, dit wil ik doen dmv een preg_replace;

PHP:
1
preg_replace('/<img src="(.*?)" /si','<img src="'.strtolower('\\1').'" ',$totaltekst);


Alleen werkt dit niet, hij wil \\1 niet in kleine letters weergeven :? Als ik \\1 verander in aap veranderd hij alles wel, dus de regex zelf klopt wel.

Hoe krijg ik dit voor elkaar?

Thanx in advance :z

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
hint: /e

Acties:
  • 0 Henk 'm!

  • sjroorda
  • Registratie: December 2001
  • Laatst online: 16:00
Even vraagje: waarom wil je dit? Als op een niet-Windows-server de afbeelding als Filename is opgeslagen, is dat case-sensitive... met jouw script krijg je deze plaatjes niet te zien!

Acties:
  • 0 Henk 'm!

  • drGoeroe
  • Registratie: Januari 2002
  • Laatst online: 04-09-2021
Waarom ik het wil maakt niet uit, ik heb een BrEeZaH versie van mijn pagina waardoor alle templates worden geconverteerd naar BrEeZaH tEkST.

Sommige images werken daardoor niet meer. Alle images zijn lowercase, dus dat maakt niet uit.

@Marcusk; de modifier e toevoegen geeft geen resultaat.

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
hmmz... 1 mom

Acties:
  • 0 Henk 'm!

  • drGoeroe
  • Registratie: Januari 2002
  • Laatst online: 04-09-2021
PHP:
1
preg_replace('/<img src="(.*?)" /si',"<img src=\"".strtolower("\\1")."\" ",$totaltekst);


Werkt nog niet :'(

Ook met de modifier e geen gewenst resultaat.
Okay :)

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
eerst maar ff uitleggen waarom dit niet werkt:
PHP:
1
2
$totaltekst = '<img src="BLA BLA" ';
preg_replace('/<img src="(.*?)" /si','<img src="'.strtolower('\\1').'" ',$totaltekst);

'<img src="'.strtolower('\\1').'" ' wordt eerst omgezet naar '<img src="\\1" '. dan gaat preg_replace de \\1 vervangen door BLA BLA, dus dat helpt niet veel.

Wat je dus moet doen is zorgen dat preg_replace strtolower uitvoert op BLA BLA. Dat kan met de /e modifier:
PHP:
1
preg_replace('/<img src="(.*?)" /sie', "strtolower('\\1')",$totaltekst);

nu gaat ie dus strtolower('BLA BLA') uitvoeren, maar heb je dus geen <img meer ervoor (dus het resultaat is alleen 'bla bla'). Dat kun je oplossen door een nieuwe functie te maken:
PHP:
1
2
3
4
function blaatschaap($str)
{
    return '<img src="' . strtolower($str) . '" ';
}
Die gebruik je dan ipv strtolower.

Acties:
  • 0 Henk 'm!

  • drGoeroe
  • Registratie: Januari 2002
  • Laatst online: 04-09-2021
Danke schon, alleen werkt het nog niet helemaal;

Ik heb een functie gemaakt;
PHP:
1
2
3
4
5
6
        function return_img ($img)
        {
            
            return "<img src=\"".strtolower($img)."\" ";
            
        }


En de regex zo;
PHP:
1
preg_replace('/[img]"(.*?)"[/img]return_img('\\1')",$totaltekst);


En de output is ALLEEN de image URL, zonder <img en nog wel in hoofdletters/kleine letters :?

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
dan moet je de $ van $this ff escapen met \.
(opzich best vaag dat dat werkt, maarja)

Acties:
  • 0 Henk 'm!

  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Hebbie dit al geprobeerd?
PHP:
1
2
3
4
5
preg_replace(
    '/<img src="(.*?)" /sie',
    "'<img src=\"' . strtolower('\\1') . '\" '",
    $totaltekst
);
Ik iig nog niet.. Misschien moet je wat spelen met escapes enzo..

On track


Acties:
  • 0 Henk 'm!

  • drGoeroe
  • Registratie: Januari 2002
  • Laatst online: 04-09-2021
marcusk; Erg vaag dat dat werkt, maar het werkt perfect :) Hartelijk dank!

@WouZz; Dat had ik al geprobeerd ja, werkte niet.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 06-07 19:12
Zo vaag is dat niet. Net zoals "$bla" wordt vervangen door een string met daarin de inhoud van $bla, wordt "$bla->die()" vervangen door het resultaat van de methode. Gewoon "die()" wordt door PHP niet herkend als een functieaanroep en blijft dus gewoon als zodanig aanwezig.

Het is logisch dat om deze constructie te laten werken, het argument in ongeëvalueerde vorm doorgegeven moet worden.

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Wat ik vaag vind is dat "\$this->f()" werkt, aangezien ik zou verwachten dat $this binnen preg_replace geen betekenis heeft.

Acties:
  • 0 Henk 'm!

  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

marcusk schreef op 01 oktober 2002 @ 14:50:
Wat ik vaag vind is dat "\$this->f()" werkt, aangezien ik zou verwachten dat $this binnen preg_replace geen betekenis heeft.
Heeft het ook niet, maar als het na de 'replace' geevalueerd wordt door PHP wel.. :)

On track


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 06-07 19:12
marcusk schreef op 01 oktober 2002 @ 14:50:
Wat ik vaag vind is dat "\$this->f()" werkt, aangezien ik zou verwachten dat $this binnen preg_replace geen betekenis heeft.
Binnen preg_replace niet, inderdaad, maar zo werkt PHP niet. PHP evalueert eerst alle argumenten en voert daarna pas de functie uit. Dat is redelijk gebruikelijk voor een programmeertaal.

De reden hiervoor is dat de code voor het evalueren van argumenten maar op een plek hoeft voor te komen en argumenten eenvoudig uit complexe expressies opgebouwd kunnen worden.

In dit voorbeeld:
PHP:
1
doeIets((5*3) + 2);

Wordt ((5 * 3) + 2) eerst geevalueerd en vervolgens wordt doeIets aangeroepen met het resultaat, 17, als argument.

Op dezelfde manier zou in het geval van:
PHP:
1
doeIets("$bla->die()");

PHP eerst $bla->die() uitvoeren, het result daarvan invoegen in de string en vervolgens die string als argument meegeven. Als $bla->die() toevallig "xxx" oplevert, krijgt de functie doeIets alleen maar "xxx" als argument te zien en kan op geen enkele manier achterhalen dat de originele expressie ooit "$bla->die()" was.

Dat merk je trouwens ook eenvoudig genoeg wanneer je zelf een functie schrijft die een enkel argument krijgt; die functie kun je ook met complexere expressies als argumenten aanroepen zonder dat je de implementatie van de functie daarvoor gewijzigd wordt.

Vervang doeIets nu door preg_replace en het moge duidelijk zijn waarom de backslash noodzakelijk is, om te voorkomen dat PHP voortijdig de expressie evalueert.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Typisch geval van een spreekwoordelijke
"Gebruik hier single quotes in plaats van double quotes"

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Soultaker schreef op 01 oktober 2002 @ 14:57:
Binnen preg_replace niet, inderdaad, maar zo werkt PHP niet. PHP evalueert eerst alle argumenten en voert daarna pas de functie uit. Dat is redelijk gebruikelijk voor een programmeertaal.
...
Dat weet ik natuurlijk wel :P
Op dezelfde manier zou in het geval van:
PHP:
1
doeIets("$bla->die()");

PHP eerst $bla->die() uitvoeren, het result daarvan invoegen in de string en vervolgens die string als argument meegeven. Als $bla->die() toevallig "xxx" oplevert, krijgt de functie doeIets alleen maar "xxx" als argument te zien en kan op geen enkele manier achterhalen dat de originele expressie ooit "$bla->die()" was.
Dat is niet waar: doeIets("$bla->die()"); voert niet $bla->die() uit. klein testje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class TestClass
{       
    var $x;
            
    function f() { return "foobar"; }
}

function blaat($x) { print($x . "<br/>"); }

$bla = new TestClass(); $bla->x = 1;

blaat("$bla->f()");
blaat("$bla->x()");
Dit print niet "foobar" zoals jij zou verwachten (?), maar "()" en een melding (met error_reporting op E_ALL):

Notice: Undefined property: f in d:\inetpub\wwwroot\test\evaltest.php on line 14

Die $x heb ik toegevoegd om te laten zien waarom ie "()" geeft. blaat("$bla->x()") print namelijk "1()": $bla->x wordt vervangen door de waarde ervan. Hetzelfde probeert ie met $bla->f, maar die property bestaat dus niet.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 06-07 19:12
Ah; blijkbaar evalueert PHP alleen variabelen en attributen (en dus geen methode) en ziet 'ie "$bla->die()" dus als het attribute $bla->die (die ongedefinieerd zal zijn) gevolgd door "()" als overgebleven string.

Dat maakt verder weinig uit voor het verhaal trouwens, al neem ik aan dat je in dat geval in ieder geval (eerder) een waarschuwing krijgt, tenzij je toevallig een attribuut met dezelfde identifier als je methode hebt.

Maar drm vat de conclusie mooi samen.

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Nog een testje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class TestClass
{       
    function f() { return "foobar"; }
    function g() { test("\$this->f()"); }
}

function blaat($x) 
{ 
    global $bla;
    print(eval($x) . "<br/>"); 
}

$bla = new TestClass();

function test($x)
{
    global $bla;
    print("$x uitvoeren geeft: <b>");
    eval("print(($x) . '<br/>');");
    print("</b>");
}

test("\$bla->f()");
$bla->g();

dit geeft de volgende uitvoer:

$bla->f() uitvoeren geeft: foobar
$this->f() uitvoeren geeft:
Fatal error: Call to a member function on a non-object in d:\inetpub\wwwroot\test\evaltest.php(24) : eval()'d code on line 1

(zoals je zou verwachten: binnen test kent ie $this niet)

Ik blijf het dus vaag vinden dat "\$this->bla()" met preg_replace wél werkt.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 06-07 19:12
OMG :o Ik had niet goed gelezen en je uitgemaakt voor zo'n domme php'er. Mijn excuses!

Ik zie nu je punt. De enige verklaring die ik zou kunnen verzinnen is dat preg_replace een functie is die 'intern' gedefinieerd is. In een PHP functie is $this uiteraard alleen van betekenis binnen een methode, maar misschien dat de Zend engine bij het aanroepen van ingebouwde functies $this niet aanpast.

Immers, eval("$this->bla") werkt ook prima, wat niet het geval zou zijn als eval echt een functie zou zijn, die de waarde van $this niet meer kan achterhalen.

Ik zou wat dieper in de Zend code moeten duiken om dat uit te vissen; iets waar ik nu helaas geen tijd voor heb...

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Soultaker schreef op 01 oktober 2002 @ 15:47:
OMG :o Ik had niet goed gelezen en je uitgemaakt voor zo'n domme php'er. Mijn excuses!
dat is wel een grove belediging ja :P hehe :)
Ik zie nu je punt. De enige verklaring die ik zou kunnen verzinnen is dat preg_replace een functie is die 'intern' gedefinieerd is. In een PHP functie is $this uiteraard alleen van betekenis binnen een methode, maar misschien dat de Zend engine bij het aanroepen van ingebouwde functies $this niet aanpast.
idd, dat denk ik ook.
Ik zou wat dieper in de Zend code moeten duiken om dat uit te vissen; iets waar ik nu helaas geen tijd voor heb...
Ik heb zelf net wel ff gekeken (preg_replace roept zend_eval_string aan), maar het is me iets te diep ;)
Pagina: 1