[PHP]Array uit preg_match blijft leeg

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 20:16
Ik ben bezig met een bbcode om te zorgen dat je met [boek]{ISBNnummer}[/boek] (en idem voor dvd's met ean-codes) een link met cover, titel en auteur krijgt naar bol.com. Om wat te testen heb ik 2 isbnnummers in een array gezet, en die haal ik vervolgens door een foreach-loop:
PHP:
1
2
3
$isbnin = array('9075504764', '9021580594');
foreach ($isbnin as $isbn)
{

Vervolgens wordt de boel netjes uitgevoerd. Tijd om het om te vormen naar een code die het ISBN-nummer uit een BBcode vist:
PHP:
1
2
3
preg_match( "#\[boek\]([0-9]+)\[/boek]#", $message, $isbnin );
foreach ($isbnin as $isbn)
{

Maar dan is het resultaat dus niets. Terwijl ik toch altijd heb begrepen dat met een preg_match de $isbnin een array wordt. Ofwel, hetzelfde als wat ik eerder in de testfase had. Waarom krijg ik dan niets eruit?

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je array blijft leeg omdat je regexp niet matched. Je moet de rechte haken escapen. Waarom staan die hashes in jouw regexp?

De reguliere expressie '\[boek\]([0-9]+)\[/boek\]' werkt bij mij perfect. Ik heb even geen PHP tot mijn beschikking maar de regexp werkt zowel in perl als C#.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

Verwijderd

Kijk eens naar het verschilt tussen preg_match en preg_match_all. Lees documentatie.

Ik zou bovendien alle slashes altijd dubbel schrijven, omdat je ook nog moet escapen i.v.m. de string.

[ Voor 38% gewijzigd door Verwijderd op 06-06-2008 09:05 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
@Niemand_Anders
De hashes zijn de notatie zoals die voor PHP benodigd zijn. Je expressie moet met een karakter naar keuze (hash in dit geval) beginnen en eindigen, omdat na het eindigen van de hash nog optionele parameters gegeven mogen worden.

@SFB
Sowieso geeft preg_match maar 1 result terug, maar die wordt inderdaad wel als array in de 3de parameter opgeslagen. Maar alleen als hij wat matched;
Kijk nog even goed naar hoe je de blokhaken escaped want je bent er 1 vergeten

[ Voor 13% gewijzigd door frickY op 06-06-2008 09:13 ]


Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 20:16
Och ja, stom dat ik die laatste haak ben vergeten te escapen.
preg_match_all had ik al geprobeerd, zonder resultaat. Logisch natuurlijk vanwege die vergeten escape.
Google heeft me inmiddels ook geleerd dat ik die de parameter U kan meegeven, zodat-ie "ungreedy" wordt. Ga ik proberen vanavond!

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Verwijderd schreef op vrijdag 06 juni 2008 @ 09:04:
Ik zou bovendien alle slashes altijd dubbel schrijven, omdat je ook nog moet escapen i.v.m. de string.
Dat is niet nodig in PHP omdat de backslash altijd letterlijk geprint wordt en alleen als escape-karakter wordt gezien als het een single of double quote voorafgaat of onderdeel is van een escape-sequence (en dat laatste alleen als je double quotes gebruikt voor je string).
Niemand_Anders schreef op vrijdag 06 juni 2008 @ 08:58:
Je array blijft leeg omdat je regexp niet matched. Je moet de rechte haken escapen. Waarom staan die hashes in jouw regexp?
In PHP kan je elk gewenst karakter gebruiken als delimiter ;)
SFB schreef op vrijdag 06 juni 2008 @ 09:29:
Och ja, stom dat ik die laatste haak ben vergeten te escapen.
preg_match_all had ik al geprobeerd, zonder resultaat. Logisch natuurlijk vanwege die vergeten escape.
Google heeft me inmiddels ook geleerd dat ik die de parameter U kan meegeven, zodat-ie "ungreedy" wordt. Ga ik proberen vanavond!
ungreedy is hier niet nodig aangezien je geen match-all karakter (dot) gebruikt.

Makkelijkst is overigens om gewoon de matches van preg_match_all te printen zodat je kan zien wat je daarmee kan doen:
PHP:
1
2
preg_match_all('#\[boek](\d+)\[/boek]#', $message, $matches);
print_r($matches);

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

crisp schreef op vrijdag 06 juni 2008 @ 11:30:

Dat is niet nodig in PHP omdat de backslash altijd letterlijk geprint wordt en alleen als escape-karakter wordt gezien als het een single of double quote voorafgaat of onderdeel is van een escape-sequence (en dat laatste alleen als je double quotes gebruikt voor je string).
Toch is het een slechte gewoonte om het niet te doen. Het is zo vreselijk eenvoudig er een foutje mee te maken.

PHP:
1
2
3
4
echo "~\n~"; // 1
echo "~\\n~"; // 2
echo "~\\\n~"; // 3
echo "~\\\\n~"; // 4

Ik merk aan mezelf dat als ik consequent alles escape wat maar enigszins nodig zou kunnen zijn, ik veel sneller een regular expression kan lezen. Overigens werken enkele quotes daarbij veel beter, omdat je dan ook niet nog eens PHP's $ voor strings hoeft gaan lopen escapen. Waarom zou je die backslashes weglaten als je ze in een ander geval wel zou laten staan? Ik prefereer het om letterlijk "\n" in mijn regular expression te zien als ik hem echo (2 dus), en niet een échte newline character (1). En als je een backslash en een newline wilt matchen, wil ik "\\n" zien (4), en niet "\
" (3)

Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

crisp schreef op vrijdag 06 juni 2008 @ 11:30:
[...]

In PHP kan je elk gewenst karakter gebruiken als delimiter ;)
Volgens mij alleen niet-alfanumerieke karakters hoor.

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 20:16
Heb het nu zo gedaan:
PHP:
1
2
3
4
5
6
7
preg_match_all('#\[boek\](\d+)\[/boek\]#',$message, $matches );
foreach ($matches as $isbnin)
    {
    $isbnin = str_replace("[/boek]", "", $isbnin);
    $isbnin = str_replace("[boek]", "", $isbnin);
    }
    unset($matches);

Werkt in elk geval, dus da's het belangrijkste, maar ik heb het idee dat het nog niet optimaal is. Je moet toch ook kunnen zorgen dat je alleen het ISBN-nummer krijgt, zonder de [boek]-tags?

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

kijk eens naar preg_replace(_callback) ;)

[ Voor 15% gewijzigd door crisp op 06-06-2008 18:34 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Het wordt nu wel een beetje treurig hoor. Je hebt dus duidelijk niet eens gekeken naar de suggestie van crisp om eens met print_r naar het resultaat van preg_match_all te kijken. Ga je eens diep schamen.

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 20:16
Verwijderd schreef op vrijdag 06 juni 2008 @ 18:36:
Het wordt nu wel een beetje treurig hoor. Je hebt dus duidelijk niet eens gekeken naar de suggestie van crisp om eens met print_r naar het resultaat van preg_match_all te kijken. Ga je eens diep schamen.
Vraag me af hoe "duidelijk", want dat heb ik dus WEL gedaan. En daaruit bleek dus dat die tags er vrolijk omheen staan. Dus moet ik ze weghalen.
Opbouwende kritiek OK, maar dit soort opmerkingen kan ik slecht tegen.

@Crisp: preg_replace_callback ziet er veelbelovend uit als ik kijk naar PHP.net
Thanks.

[ Voor 0% gewijzigd door Tjolk op 06-06-2008 19:00 . Reden: typo ]

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

Verwijderd

SFB schreef op vrijdag 06 juni 2008 @ 18:58:

Vraag me af hoe "duidelijk", want dat heb ik dus WEL gedaan.
Zo duidelijk dat deze persoon die die functie honderden keren heeft toegepast uit zijn hoofd weet dat het resultaat een array is, met in die array weer arrays van matches per capturing group. Als jij dus even langer had gekeken dan had je gezien dat in $matches[1] keurig al je ISBN nummers staan.
Zo duidelijk.
En daaruit bleek dus dat die tags er vrolijk omheen staan. Dus moet ik ze weghalen.
Kijk nog eens (ja, met print_r), en probeer dan met droge ogen te beweren dat je daar zomaar overheen hebt gekeken.
Opbouwende kritiek OK, maar dit soort opmerkingen kan ik slecht tegen.
Vervelend voor je. Maar dan kun je hier maar beter vragen meer gaan stellen zonder iets te doen met de suggesties die je krijgt. En dan moet je dus niet gaan verkondigen dat je preg_match_all al had geprobeerd (zonder resultaat) als je erop gewezen wordt dat je daarmee je doel kunt bereiken als je maar even de documentatie leest. Dan kijk je eerst nog een keer en concludeer je dat je niet goed had gekeken. Dat deed je echter neit.
Vervolgens wordt er in de volgende reactie nogmaals op gewezen dat preg_match_all doet wat je wilt, en dat je naar het resultaat moet kijken met print_r.
Wat daar weer op volgt is een stukje code post waarin je de matches array van preg_match_all verkeerd gebruikt, waaruit blijkt dat je 1) de documentatie niet goed hebt gelezen, en 2) niet (goed) hebt gekeken naar de matches met print_r.

En daarom moet je je schamen. Als je een nog uitgebreidere analyse wilt heb je pech, ik ben hier wel klaar mee. Hopelijk doe je iets met deze opbouwende kritiek.

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 20:16
Verwijderd schreef op vrijdag 06 juni 2008 @ 19:39:Kijk nog eens (ja, met print_r), en probeer dan met droge ogen te beweren dat je daar zomaar overheen hebt gekeken.
Ik ga hier niet verder op in dat te wijzen op mijn signature en te melden dat ik het nog niet door had. En ik schrijf dit met gortdroge ogen.

Je zou eens moeten begrijpen dat niet iedereen een volleerd programmeur is. En volgens de richtlijnen hier hoeft dat ook niet: zolang men maar leert. En leren doe je met vallen en opstaan.

[ Voor 20% gewijzigd door Tjolk op 11-06-2008 08:08 ]

Tjolk is lekker. overal en altijd.

Pagina: 1