[PHP/Regex] Regex matcht teveel

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Hi ladz,

Ik probeer hier een WordPress plugin een beetje te editen, hij matcht teveel in de regex.

De bedoeling is dat iedere link met een gif|png|bmp|jpe?g geparsed wordt naar dezelfde link, met een rel=lightbox erin.

Daarvoor is er de volgende code:

PHP:
1
2
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>/i";
$replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>';


Het probleem gebeurt wanneer in 1 regel dit staat:
HTML:
1
<a href="linknaarfoto.bmp">klikky</a> tekst <img src="smilie.png" ... />


Dan matcht die regex heel die regel. Wat dat niet de bedoeling is. Ik heb na lezen gevonden dat dit wil zeggen dat die regex te greedy is.

Ik heb de volgende patterns geprobeert.
PHP:
1
2
3
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>[^>]/i";
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)[^>]>/i";
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.[^>]*?)>/i";


Maar geen enkele is ungreedy genoeg. Kan iemand * Snake in de goede richting schoppen?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 12:37

Gonadan

Admin Beeld & Geluid, Harde Waren
Waarom geef je niet gewoon de ungreedy modifier (U) mee? :?

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • pkuppens
  • Registratie: Juni 2007
  • Laatst online: 18-09 07:32
Snake schreef op maandag 10 december 2007 @ 10:42:
Hi ladz,

Ik probeer hier een WordPress plugin een beetje te editen, hij matcht teveel in de regex.

De bedoeling is dat iedere link met een gif|png|bmp|jpe?g geparsed wordt naar dezelfde link, met een rel=lightbox erin.

Daarvoor is er de volgende code:

PHP:
1
2
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>/i";
$replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>';


Het probleem gebeurt wanneer in 1 regel dit staat:
HTML:
1
<a href="linknaarfoto.bmp">klikky</a> tekst <img src="smilie.png" ... />


Dan matcht die regex heel die regel. Wat dat niet de bedoeling is. Ik heb na lezen gevonden dat dit wil zeggen dat die regex te greedy is.

Ik heb de volgende patterns geprobeert.
PHP:
1
2
3
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>[^>]/i";
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)[^>]>/i";
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.[^>]*?)>/i";


Maar geen enkele is ungreedy genoeg. Kan iemand * Snake in de goede richting schoppen?
[Ongetest:] Mijn suggestie is dat je al je .'s door [^>] wil vervangen. Je loopt nu uit je 'anchor' al door je eerste .*.

De ungreedy modifier zoals elders genoemd is ook een optie. Ik denk op het 1e patroon.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Gonadan schreef op maandag 10 december 2007 @ 10:44:
Waarom geef je niet gewoon de ungreedy modifier (U) mee? :?
Blijkbaar niet zo simpel,
PHP:
1
    $pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>/Ui";
Dan is hij nog steeds te greedy

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • rogierslag
  • Registratie: Maart 2005
  • Laatst online: 14-10-2024
HTML:
1
[u]<a[/u] href="linknaarfoto.bmp">klikky</a> tekst <img src="smilie.png" ... [u]/>[/u]


Ik heb even de respectievelijke begin en eindpunten aangegeven door onderstreping. Dat nu de hele regel gepakt wordt is niet gek, je geeft geen einde aan, immers alle mogelijke tekens vallen onder die (.*?) voorwaarde. Door die allerlaatste > wordt geparsed als laatste teken van je expressie

Werkt het met deze regex wel

PHP:
1
2
3
4
<?php 
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>(.*?)<\/a>/i"; 
$replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>'; 
?>


Deze matcht namelijk direct op die sluitende </a> tag.

Met je huidige regex zou je ook problemen krijgen bij iets als
code:
1
<a href="linknaarfoto.bmp"><b>klikky</b></a>


Verder heb ik het niet getest, dus misschien moet je nog iets tweaken

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
rogierslag schreef op maandag 10 december 2007 @ 11:45:
HTML:
1
[u]<a[/u] href="linknaarfoto.bmp">klikky</a> tekst <img src="smilie.png" ... [u]/>[/u]


Ik heb even de respectievelijke begin en eindpunten aangegeven door onderstreping. Dat nu de hele regel gepakt wordt is niet gek, je geeft geen einde aan, immers alle mogelijke tekens vallen onder die (.*?) voorwaarde. Door die allerlaatste > wordt geparsed als laatste teken van je expressie

Werkt het met deze regex wel

PHP:
1
2
3
4
<?php 
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>(.*?)<\/a>/i"; 
$replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>'; 
?>


Deze matcht namelijk direct op die sluitende </a> tag.

Met je huidige regex zou je ook problemen krijgen bij iets als
code:
1
<a href="linknaarfoto.bmp"><b>klikky</b></a>


Verder heb ik het niet getest, dus misschien moet je nog iets tweaken
Dit werkte bijna :+

Heb 'm aangepast, en dit is het resultaat:
PHP:
1
2
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>(.*?)<\/a>/i";  
    $replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>$7</a>';


Werkt perfect, dankuwel _/-\o_

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • rogierslag
  • Registratie: Maart 2005
  • Laatst online: 14-10-2024
Snake schreef op maandag 10 december 2007 @ 12:04:
PHP:
1
2
$pattern = "/<a(.*?)href=('|\")(.*?).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>(.*?)<\/a>/i";  
    $replacement = '<a$1href=$2$3.$4$5 rel="lightbox[%LIGHTID%]"$6>$7</a>';
Die replacement even die $7 bijzetten was ik idd vergeten. Krijg je op de vroege ochtend :p
Pagina: 1