[PHP]Url's op een webpagina vinden via preg_match_all()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 13:59

Kajel

Development in Style

Topicstarter
Hey allen!

Voor mijn werk ben ik bezig een migratiescript te schrijven klanten van de oude versie van ons CMS naar de nieuwe versie over te zetten. Daarbij moeten ook linkjes naar bestanden die middels het CMS zijn geupload, vervangen worden. Die linkjes zien er zo uit:
oud: http://www.somesite.com/?file=243 (243 is een voorbeeld id, kan elk getal zijn)
nieuw: http://www.somesite.com/file/some-fancy-slug

Nou wat het schrijven van een functie die zo'n oude id omzet in de slug van het nieuwe systeem, geen probleem. Wat wel een probleem is, is het vinden van alle oude linkjes op een pagina middels preg_match_all

De volgende pattern had ik bedacht, met hulp van een collega: '/^.*(http:\/\/.+\/\?file=(\d+)).*$/mis'
Probleem is dat deze op een pagina met meerdere matches, maar 1 match vindt. Moet ik ook eerlijk bij zeggen, dat de pattern mede bedacht is door mijn collega, en ik sommige keuzes niet helemaal begrijp.

Dus ben ik zelf opnieuw begonnen, en heb ik geprobeerd het zo makkelijk mogelijk te houden. Ik kwam uit op het volgende: '/.*?http:\/\/.+\/\?file=(\d+).*?/is' Geeft er ook maar 1 terug!

Ik gebruik voor het testen de volgende site: http://www.functions-online.com/preg_match_all.html
Als testdata gebruik ik gewoon dit:
"http://www.aram-rocks.com/?file=132
http://www.aram-rocks.com/?file=133
http://www.aram-rocks.com/?file=134"

(met enters ertussen dus)

code:
1
2
3
4
5
6
7
8
9
array (
  0 => 
  array (
    0 => 'http://www.aram-rocks.com/?file=132
             http://www.aram-rocks.com/?file=133
             http://www.aram-rocks.com/?file=134',
    1 => '134',
  ),
)


Kan iemand me opweg helpen, met hoe ik meerdere matches kan vinden?

Acties:
  • 0 Henk 'm!

  • Sendy
  • Registratie: September 2001
  • Niet online
Geeft een regexp niet altijd maar een match terug? Ik zou niet weten hoe een match meerdere resultaten zou teruggeven. Een loopje en een opschuivende string lost dat op?

edit:

Ik zie nu ook dat preg_match_all gedaan wordt. Mijn eerdere opmerking is dus onzin :)

[ Voor 23% gewijzigd door Sendy op 16-02-2011 14:34 ]


Acties:
  • 0 Henk 'm!

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 17-09 14:06
Kajel schreef op woensdag 16 februari 2011 @ 12:35:
Hey allen!
code:
1
 '/(http:\/\/.+\/\?file=(\d+))/i'
Dat zou het moeten doen.

Als je ^.*$ gebruikt match je altijd alles, preg geeft dan alleen de eerste match tussen haakjes terug (wat volgens mij heel logisch is)

@hierboven:
Het is een array met results dat je terug krijgt

[ Voor 20% gewijzigd door trinite_t op 16-02-2011 13:50 ]

The easiest way to solve a problem is just to solve it.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

.+ is ivm greedyness ook niet echt handig; maak dat deel gewoon specifiek voor de site...

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 13:59

Kajel

Development in Style

Topicstarter
crisp schreef op woensdag 16 februari 2011 @ 13:47:
.+ is ivm greedyness ook niet echt handig; maak dat deel gewoon specifiek voor de site...
Lijkt me juist wel handig, want als ik 'file=(\d+)' ungreedy maak, dan stopt ie na het eerste getal toch?

Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 13:59

Kajel

Development in Style

Topicstarter
Sendy schreef op woensdag 16 februari 2011 @ 13:24:
Geeft een regexp niet altijd maar een match terug? Ik zou niet weten hoe een match meerdere resultaten zou teruggeven. Een loopje en een opschuivende string lost dat op?
preg_match_all, in tegenstelling tot preg_match, geeft meerdere resultaten terug.

Acties:
  • 0 Henk 'm!

  • Sendy
  • Registratie: September 2001
  • Niet online
Jaja, sorry voor die opmerking. Het was onzin idd. Ik heb mijn eerdere post gewijzigd.

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 13:59

Kajel

Development in Style

Topicstarter
trinite_t schreef op woensdag 16 februari 2011 @ 13:40:
[...]

code:
1
/(http:\/\/.+\/\?file=(\d+))/i


Dat zou het moeten doen.

Als je ^.*$ gebruikt match je altijd alles, preg geeft dan alleen de eerste match tussen haakjes terug (wat volgens mij heel logisch is)

@hierboven:
Het is een array met results dat je terug krijgt
Dat werkt, totdat de links niet meer op een aparte regel staan, maar aan elkaar, bv:
code:
1
2
<a href="http://www.aram-rocks.com/?file=132">bla</a><a href="http://www.aram-rocks.com/?file=133">bloe</a>
http://www.aram-rocks.com/?file=134

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Ik gebruik meestal deze. Kan strikter, maar werkt doorgaans prima;
PHP:
1
preg_match_all("/<a.* href=\"(?!#)(?!mailto:)(?!javascript:)(.*)\".*>/isU", $sBody, $aPreg);

[ Voor 10% gewijzigd door frickY op 17-02-2011 11:09 ]


  • Lye
  • Registratie: Januari 2010
  • Laatst online: 16:10

Lye

Wat is er mis met het gebruik van een DOM parser? Je zou uberhaupt geen reguliere expressies moeten gebruiken voor HTML.

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Kajel schreef op donderdag 17 februari 2011 @ 10:54:
[...]

Dat werkt, totdat de links niet meer op een aparte regel staan, maar aan elkaar, bv: [...]
Ja, vandaar mijn opmerking over .+ en greedyness ;)

Intentionally left blank


  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Lye schreef op donderdag 17 februari 2011 @ 13:05:
Wat is er mis met het gebruik van een DOM parser? Je zou uberhaupt geen reguliere expressies moeten gebruiken voor HTML.
Omdat HTML niet per definitie zo strict is als XML (afhankelijk van de luiheid van de ontwikkelaar). M.a.w. 1 niet gedefinieerde closing tag en je DOM parser zou wel eens onderuit kunnen gaan.

Browsers e.d. zijn in die zin best vergevend :)

[ Voor 7% gewijzigd door Laurens-R op 17-02-2011 13:45 ]


  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Laurens-R schreef op donderdag 17 februari 2011 @ 13:44:
[...]


Omdat HTML niet per definitie zo strict is als XML (afhankelijk van de luiheid van de ontwikkelaar). M.a.w. 1 niet gedefinieerde closing tag en je DOM parser zou wel eens onderuit kunnen gaan.

Browsers e.d. zijn in die zin best vergevend :)
Een DOM parser zou toch net als de parser van een browser te werk moeten gaan? HTML5 definieert het parsing-algoritme zelfs tot in de kleinste details, en zodra alle browsers hetzelfde algoritme geimplementeerd hebben kunnen we dat hoofdstuk dus eindelijk eens afsluiten :)

Maar persoonlijk vind ik een DOM-parser inzetten voor zoiets triviaals als het omzetten van een paar linkjes die eigenlijk onambigueus gematched kunnen worden nogal overkill ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 13:59

Kajel

Development in Style

Topicstarter
DOM-parser lijkt me idd overkill, naast het feit dat die under-the-hood natuurlijk ook gewoon met Regex werkt ;)
crisp schreef op donderdag 17 februari 2011 @ 13:12:
[...]

Ja, vandaar mijn opmerking over .+ en greedyness ;)
Ja, maar ik zie niet in waarom ik de (d+) ungreedy moet maken. Die zoekt alleen getallen, dus als ik die ungreedy ga maken dan gebeuren er 2 dingen:
- file=2434 levert met dan volgens mij alleen "2" op.
- Aangezien t over getallen gaat, lost het nog steeds niet het probleem op, dat achter elkaar staande links, zonder whitespace, niet als aparte links gezien worden.

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Waarom niet gewoon ?file=123 blijven supporten, en ze laten redirecten naar de goede nieuwe pagina? Dat scheelt heel veel zoekwerk, en zorgt er ook voor dat niet-gevonden (dus bv. ook op andere sites) links ook blijven werken.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Kajel schreef op maandag 21 februari 2011 @ 09:50:
DOM-parser lijkt me idd overkill, naast het feit dat die under-the-hood natuurlijk ook gewoon met Regex werkt ;)


[...]

Ja, maar ik zie niet in waarom ik de (d+) ungreedy moet maken.
Ik heb het niet over de \d+ maar over de .+

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 17:19
RobIII schreef op maandag 21 februari 2011 @ 13:27:
[...]

Ik mag hopen dat een beetje DOM parser gebruik maakt van een lexer en niet een regex :X
Lexers werken over het algemeen ook met regexes die vertaald/ gecompileerd worden. Ze worden meestal niet met de hand geschreven.

RobIII, doe's niet je eigen reactie verwijderen, foei :P

[ Voor 52% gewijzigd door Jaap-Jan op 21-02-2011 13:40 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Jaap-Jan schreef op maandag 21 februari 2011 @ 13:37:
Lexers werken over het algemeen ook met regexes die vertaald/ gecompileerd worden. Ze worden meestal niet met de hand geschreven.
Ik reageerde wat vlug :P
Jaap-Jan schreef op maandag 21 februari 2011 @ 13:37:
RobIII, doe's niet je eigen reactie verwijderen, foei :P
O-)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1