[PHP] preg replace pakt 1 match niet

Pagina: 1
Acties:

  • red_indian
  • Registratie: Maart 2000
  • Laatst online: 24-06 16:43

red_indian

 Smokin' Suckz B!

Topicstarter
ik kom er niet meer uit. van alles al geprobeerd. niet het bekende greedy probleem. maar wat wel?
PHP:
1
2
3
4
5
6
<?
  $fdata = "[img]http://www.regeert.nl[/img]";

  // ' = '
  $data=preg_replace("/ (.*?)=(.*?) /i", " \\1=\"\\2\" ", $fdata);
?>

Afbeeldingslocatie: http://www.regeert.nl (input)
[img]"http://www.regeert.nl"[/img] (output)

zoals je ziet pakt hij netjes de 'src=' en de 'henk=', maar niet de 'width='. iemand?

extra:
en als iemand mij een 1 liner kan geven om alles wat niet tussen quotes staat wel tussen quotes te zeten is dat ook niet verkeerd :+

met uitzondering van wat al tussen quotes staat uiteraard ;)

alvast bedankt voor je/jullie input!

Need a cuesheet/tracklisting? (meer dan 500.000 online)


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
code:
1
2
3
$fdata = '[img]http://www.regeert.nl[/img]';
     
$data = preg_replace("/(.+?)=([^\"]+?[^\"])( |>)/i", "\\1=\"\\2\" ", $fdata);

dat werkt

  • tomato
  • Registratie: November 1999
  • Niet online
Pleas allow me :P

Ik zat er nog even mee te spelen en kwam tot het volgende in perl. Rekening wordt gehouden met een = binnen een doublequoted atribuut (wat bij de regex van marcusk fout zal gaan) en verder met dingen als eventuele escaped quotes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$s =~ s/

        # kom laten we attributen zoeken!

        (
            =                   # start
            (

                "               # open quote
                (
                    [^"\\]*     # (normal)
                    (
                        \\.   # (special)
                        [^"\\]*    # (normal)
                    )*
                )
                "               # sluit quote

            |                   # OF

                [^ \n\t>]*       # geen quotes

            )
        )

        # klaar

/'="' . ( defined($3) ? $3:$2 ) . '"'/xgse;

Dit doublequote alle niet gequote attributen en laat andere met rust. Er wordt uitgegaan van reeds correcte HTML.
Er worden slechts losse tags verwacht, niet een geheel HTML document. Dan kan het namelijk mis gaan wanneer er een = buiten een tag voor komt. Dit lijkt me vrijwel onmogelijk te verhelpen in 1 regex, ik zou eerst splitten op alle tags (rekening houdend met gequote > en < etc) en deze vervolgens op gegeven manier bewerken.
Ander minpuntje zou nog zijn dat er alleen gekeken wordt naar doublequotes, met wat spelen zou hij compleet kunnen worden door ook naar singelquotes te kijken.

Ik ben niet helemaal helder meer op dit moment dus misschien zit er een foutje in, maar voor zover ik hier even bekeken heb werkt ie aardig :)

(mbravenboer, lees er maar overheen ofzo, of neem aan dat regex hacking verslavend is :+)

[edit] Comments toegevoegd in pattern

  • tomato
  • Registratie: November 1999
  • Niet online
Oja, misschien nog aardig om even te zeggen waarom red_indian's eerste regex niet goed werkte. Door de spaties. Je spatie achterin je match laat de volgende match voorbij die spatie beginnen, maar omdat je ook wilt beginnen met een spatie begint de volgende match een stukje verderop (wanneer je je attributen gescheiden hebt door enkele spaties zul je dus effectief om en om wel en geen quotes toevoegen).

  • red_indian
  • Registratie: Maart 2000
  • Laatst online: 24-06 16:43

red_indian

 Smokin' Suckz B!

Topicstarter
bedankt mensen, ik ben zelf gisteravond op dit uitgekomen (tja, got was down en je moet toch wat ;)):
PHP:
1
2
3
4
<?
    $text  = preg_replace("/(.*?)=(?!(\"))([^ ]*?)(?!(\"))>/i", "\\1=\"\\3\">", $text);
    $text  = preg_replace("/(.*?)=(?!(\"))([^>]*?)(?!(\")) /i", "\\1=\"\\3\" ", $text);
?>

ik gebruik hier een dubbele want anders gaat een ongequote attribuut voor een > niet goed. dan krijg je bijv.

<a name=henk> (input)
<a name="henk" (output)

hij match nl. de spatie of '>' en vervangt deze altijd door een spatie.

van mij is beetje onnodig complex zie al wel.
maar bedankt voor de uitleg want ik had hetzelfde probleem al weer een keer toen ik '<LI>' altijd wilde afsluiten met een preg_replace. ging prima, alleen dan pakte hij er precies weer 1 niet.

zal straks eens even kijken of dit nu opgelost is.

Need a cuesheet/tracklisting? (meer dan 500.000 online)


  • tomato
  • Registratie: November 1999
  • Niet online
red_indian: hij match nl. de spatie of '>' en vervangt deze altijd door een spatie.
Dat kun je in ieder geval gemakkelijk oplossen door zoiets:
PHP:
1
2
3
<?
$s = preg_replace("/([ >])/", "$1", $s);
?>

Dit vervangt een spatie door een spatie en een > door een > (ok, ik geef toe dat het voorbeeld een beetje onzinnig is ;)).

  • red_indian
  • Registratie: Maart 2000
  • Laatst online: 24-06 16:43

red_indian

 Smokin' Suckz B!

Topicstarter
woow! bedankt allen! 8-)

de 1-liner:
PHP:
1
2
3
<?
    $text = preg_replace("/(.*?)=([^\"]*?[^\"])([ >])/i", "\\1=\"\\2\"\\3", $text);
?>

post score: 1 (overbodig) :+

edit:
'+' moet dus wel een '*' zijn

Need a cuesheet/tracklisting? (meer dan 500.000 online)

Pagina: 1