Hvordan bruke regulære uttrykk i PHP

Etter at jeg skrev Hvordan lage regulære uttrykk for en del tid tilbake, tenkte jeg nå at jeg skulle skrive litt om hvordan man bruker reguløre uttrykk i PHP. Dette er hovedsakelig grunnet lenge siden forrige post, og noe respons på at forrige artikkel manglet dette.

Man kan samle bruksområdet til regulære uttrykk i 2 hovedgrupper. Disse er søk/matching og erstatting. Under søk/matching finner vi funksjoner som preg_match () og preg_match_all (). I den andre gruppen finner vi blant annet preg_replace (). Det finnes også flere funksjoner, de kommer jeg tilbake til senere. Alt av regex går på manipulering av data. Det finnes også flere funksjoner i preg_* serien, men jeg kommer ikke til å gå igjennom alle av de. Jeg går igjennom 3 funksjoner, som er de som oftes blir brukt. Det er veldig lett å finne ut av resten når du kan disse grunnleggende tre. Det er bare å lære seg disse og se på forskjellene med de andre i PHP Manualen

Som dere kanskje ser er det preg_*-funksjoner som blir brukt til regulære uttrykk nå til dags. Tidligere ble det brukt ereg*-funksjoner, men de er nå utgått pga stor hastighetsforskjell.

Søk/matching

Dette brukes om du skal sjekke om noe (gjerne ukjent) eksisterer i en streng. Det blir da søking etter noe eller matche strenger som har en viss dynamikk i seg. I all hovedsak er det snakk om preg_match() og preg_match_all().

Det er relativt liten forskjell på disse to. *_all blir brukt når det er forventet flere resultater av matchingen i mønstret på stringen du har satt. Du setter en tom array i et argument for å få resultatene du henter ut. Du bruker ikke *_all om du skal sjekke om noe eksisterer i en streng. Den returnerer antallet av matcher som oppstår, på samme måte som den vanlige preg_match funksjonen, og false ved feil, men så lenge du bruker den i en boolsk if-statment er det ikke noe poeng å bruke preg_match_all () siden alt over 1 er true, og det greier preg_match å gjøre selv.

Noen eksempler på bruk av preg_match() og preg_match_all ()

Nå i det siste har jeg brukt veldig mye regulære uttrykk mens jeg har jobbet på IMDb_Fetch. Der er det genialt å bruke regex. Du henter ut en ukjent informasjon som befinner seg i et visst mønster.

Skal jeg f.eks sjekke om det er tall i en streng, kan jeg bruke simpel boolsk returnering av preg_match. Det kan jeg da gjøre på dette viset:

  1. <?php
  2. $string = 'Hei, dette er en tekst med tall 1234';
  3. if(preg_match('/\d/', $string)) {
  4.     // Det er tall i strengen $string
  5. }
  6. ?>

Dette vil da være true, siden vi finner tall i strengen. Dette er veldig simpel søking eller matching om du vil. Om jeg vil ha tallene som er i retur kan jeg legge til en tom array på et argument (tredje), som viser meg hva som blir funnet.

  1. <?php
  2. $string = 'Hei, dette er en tekst med tall 1234';
  3. $matches = array();
  4. if(preg_match('/[\d]+/', $string, $matches)) {
  5.    // Det er tall i strengen $string
  6.    print_r($matches);
  7.    /* Viser:
  8.       Array
  9.       (
  10.          [0] => 1234
  11.       )
  12.    */
  13. }
  14. ?>

Dette er et kjapt eksempel på hvordan du kan se etter om noe finnes, og hente ut informasjon. Men hva om jeg har en lang streng med informasjon som jeg vil hente ut.

Tenk oss den fiktive problemstillingen at jeg har en liste av personer med alder, som jeg vil hente ut. Dette er da en ordnet liste fra et HTML-dokument. Dokumentet ser slik ut:

  1. <li>Grete: 34 år</li>
  2. <li>Hans Marius: 18 år</li>
  3. <li>Espen Andreas Bergen: 74 år</li>
  4. </ol>

Her vil jeg altså hente ut navn, og alder. Dette skal være gruppert for hver linje. Så jeg lager et mønster som går for en linje, og bruker preg_match_all () for å repitere mønsteret så jeg får hentet ut alle tre navnene.

  1. <?php
  2. $string = '<ol>
  3. <li>Grete: 34 år</li>
  4. <li>Hans Marius: 18 år</li>
  5. <li>Espen Andreas Bergen: 74 år</li>
  6. ';
  7. $matches = array();
  8.  
  9. // Uttrykket følger det mønsteret jeg ser er på hver linje av det
  10. // relevante jeg vil hente ut. Det er noen særpreg som er statiske
  11. // på linjene. Dette er li-taggen, kolon og "år". Da er det lett å hente
  12. // ut informasjonen.
  13. $regex = '/<li>(?P<name>[\w ]*):\s*(?P<age>[\d]+)\s*år<\/li>/';
  14. if(preg_match_all($regex, $string, $matches)) {
  15.     // Det ble funnet resultat
  16.     print_r($matches);
  17. }
  18. ?>

Der bruker jeg Named Capture Grouping for å få bedre kontroll over resultatene, og få innbakt det i et eksempel også. Resultatet i $matches vil være noe følgende:


Array
(
[0] => Array
(
[0] =>

  • Grete: 34 år
  • [1] =>

  • Hans Marius: 18 år
  • [2] =>

  • Espen Andreas Bergen: 74 år
  • )

    [name] => Array
    (
    [0] => Grete
    [1] => Hans Marius
    [2] => Espen Andreas Bergen
    )

    [1] => Array
    (
    [0] => Grete
    [1] => Hans Marius
    [2] => Espen Andreas Bergen
    )

    [age] => Array
    (
    [0] => 34
    [1] => 18
    [2] => 74
    )

    [2] => Array
    (
    [0] => 34
    [1] => 18
    [2] => 74
    )

    )

    Sånn er det lett å hente ut informasjonen vi vil med å bruke $matches['name'][0] for navnet på første personen og $matches['age'][0] for alderen på første personen. Veldig lett å finne frem. Da har vi søkt etter data om ukjente personer og hentet ut ukjent informasjon med regulære uttrykk.

    Erstatting av ukjent innhold

    Hele poenget med regexp er jo at du skulle kunne behandle informasjon som kanskje er ukjent for deg. Du vet noen kriterier, men ikke det nøyaktige innholdet, som kan variere fra gang til gang. Om det ikke hadde vært en viss dynamikk i det kunne du ha brukt andre funksjoner som strpos() eller str_replace() for erstatting.

    La oss si at jeg skal lage brukervennlige adresser ut av tittel. Slik som f.eks wordpress gjør, eller mange, mange andre CMS. Dette er en veldig vanlig problemstilling. Da må jeg først se hvilke tegn som kan brukes. Dette er kun vanlige små alfa-bokstaver (a-z), tall, bindestrek og understrek. Dette er det mest vanlige for titler. Det vi vil gjøre da er å fjerne alt det andre.

    1. <?php
    2. $string = 'Min fiNe tiTtel med 123, ØÆÅ og @@#$';
    3.  
    4. // Gjør først alt til små bokstaver. ØÆÅ blir
    5. // ikke tatt av strtolower (), så vi må gjøre det selv
    6. $string = strtolower ($string);
    7.  
    8. $scandic_letters = array('Ø', 'Æ', 'Å',
    9. 'ø','æ','å');
    10. $scandic_transformed = array('oe', 'ae', 'aa',
    11.  'oe', 'ae', 'aa');
    12.  
    13. // Først lager vi om de ikke-godkjente
    14. // bokstavene til noe som kan forstås
    15. // Her er det statiske verdier så vi bruker
    16. // str_replace
    17. $title = str_replace ($scandic_letters,
    18. $scandic_transformed, $string);
    19.  
    20. // Så gjenstår det å fjerne alt det som ikke
    21. // er tillatt og gjøre om mellomrom til -
    22. $title = preg_replace ('/[\s]+/', '-', $title);
    23.  
    24. // Fjerne ugyldige tegn
    25. $title = preg_replace ('/[^\w-]/', '', $title);
    26.  
    27. echo $title;
    28. // Vil vise: min-fine-tittel-med-123-oeaeaa-og-
    29. ?>

    Da har vi oppnådd det vi ville. Det er en dynamikk i det, og den låser seg ikke til den faste tittelen, men på alle tekster og du kan kjøre alt igjennom der for å få en gyldig streng som kan brukes i en tittel.

    Dette var en veldig kjapp gjennomgang på hvordan en kan bruke regulære uttrykk i PHP. Jeg har desverre ikke mer tid til å skrive noe i dag.

    Legg igjen respons

    Fyll ut alle felt markert med *

    Brukerinformasjon
    1. Kan bruke følgende html: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> og [html] [css], [mysql] og [php] Hold posten ren og fin!

      Siter valgt tekst

    E-post-varsel uten å skrive kommentar.

    Info om posten

    Innlegget ble postet 18.11.07 15:32 og ligger under kategorien PHP / MySQL. Du kan abonnere på kommentarene ved å bruke RSS 2.0 feed. Du kan legge til kommenter, eller trackback fra din blogg/side.

    Resurser

    Arkiver

    Metainfo


    Siste Flickr-bilder

    • Commentsystem (20070308)
    • Ukraina Aksjonen 2006 (20070306)
    • Mikael Brevik blogg (20070306)
    • Mikael Brevik (20070306)
    • Brukerdefinert side - AVIS2 (20070306)
    • Brevik Webutvikling (20070306)
    • skyscraper
    • visittkort