Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[REGEXP] - Een woord dat NIET in een string mag voorkomen.

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

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Voor een regexp match heb ik de volgende (voorbeeld)-string:
code:
1
2
3
4
Meer info:<br/>
<a href='http://www.domein.nl' target="_blank">Een externe link</a><br>
<a href='link.html'>Een interne link</a><br>
<a href='http://www.domein.nl' target="_blank">Een externe link</a><br>


Nu wil ik graag een match maken die begint bij "Meer info:" en vervolgens de externe links uit de daarop volgende regels haalt.

Ik heb nu als Perl regexp het volgende om alleen even voor elkaar te krijgen dat "Meer info:" t/m de eerste "<a" wordt gematched. Dat werkt niet, omdat ik het niet voor elkaar krijg om de hele term "<a" negatief te laten beoordelen. De volgende opties heb ik geprobeerd:
PHP:
1
2
3
4
5
6
$regexp = '%Meer info:^(<a).*<a%mi';
$regexp = '%Meer info:^[<a].*<a%mi';
$regexp = '%Meer info:[^<a].*<a%mi';
$regexp = '%Meer info:(^<a).*<a%mi';
$regexp = '%Meer info:(!<a).*<a%mi';
$regexp = '%Meer info:!(<a).*<a%mi';


Zou iemand mij uit de brand willen helpen? Ik kan nergens hoe ik een string als geheel kan laten optreden als "if-not" conditie.

Alvast bedankt!

Overigens ... de volgende regexp:
PHP:
1
$regexp = '%Meer info:.*<a%mi';


Matcht wél wat, maar die matcht dan meteen t/m de laatste keer dat "<a" in de string voorkomt, dus inclusief de eerste twee links.

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Kun je het niet beter in 2 keer doen?

Dus matchen van meer info: t/m </a> en dan nog een keer een regex eroverheen die de links eruit haalt?

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Fiander
  • Registratie: Februari 2001
  • Laatst online: 28-05 12:35
Weet je zeker dat je bij die laatste maar één antwoord krijgt ?

Ik zou verwachten dat je een array terug krijgt met daarin drie keer één string.
Waarin dan elke <a een keer als eindpunt gezien word.

hoe is je regex gedefineert ? greedy of niet greedy

Deze sig is een manueel virus!! Als je dit leest heb je het. Mail dit bericht naar iedereen die je kent, en verwijder alle bestanden van je computer.


  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
In bovenstaande voorbeelden stond de regexp ingesteld op greedy. Ik ben nu aan het experimenteren met NIET-greedy. Dat levert betere resultaten op.

Grootste probleem waarbij ik echter zit is dat ik geen negated strings kan maken.

Ik kan zeggen:
PHP:
1
$regexp = '%[^>].*%mis';

En dat pakt alles dat geen > in zich heeft.

Maar ik krijg niet voor elkaar:
PHP:
1
$regexp = '%[^(</a>)].*%mis';


Dat even als - niet werkend - voorbeeld van wat ik bedoel. Ik wil dus eigenlijk alles matchen _behalve_ </a>. Maar de circonflex (^) kan volgens mij alleen op deze manier worden gebruik in character classes [ ], waar juist alle karakters als alternatieve optie worden gezien.
Kun je het niet beter in 2 keer doen?

Dus matchen van meer info: t/m </a> en dan nog een keer een regex eroverheen die de links eruit haalt?
Dat zou alle links weghalen, dus ook die los van dat "Meer info" staan. Da's dan weer niet de bedoeling.

Bovendien ben ik dit al veel vaker tegengekomen. Ergens zit er dus blijkbaar een denkfout bij mij ... in plaats van daar omheen werken wil ik graag leren hoe ik dit goed moet aanpakken.

[ Voor 25% gewijzigd door gvanh op 29-11-2007 09:44 . Reden: aanvulling met quote. ]


  • Fiander
  • Registratie: Februari 2001
  • Laatst online: 28-05 12:35
Ben het met 4of9 eens dat het het makkelijkste zou zijn om het in twee keer te doen. ( toch eens vaker refreshen )

eerst een string ophalen tot de laatste </a en daarna uit deze string de linken halen.
waarschijnlijk met iets als '%Meer info:.*</a%mi' ( greedy )

en daarna met iets als dit '<a.+href=\"(.+?)\"' de linken eruit vissen.

Deze sig is een manueel virus!! Als je dit leest heb je het. Mail dit bericht naar iedereen die je kent, en verwijder alle bestanden van je computer.


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Wat is jou definitie van "los van meer info"?

Als je niet duidelijk kunt bepalen wat het einde moet zijn van je te matchen set vraag ik me af of je er mee gaat komen dmv. regex. Als je wel duidelijk het einde kunt definieeren blijft mijn aanpak hetzelfde:

Pluk eerste Meer info: tot einde van set.

Pak dan alle externe links (in je voorbeeld alle links die een target bevatten).

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Ja, misschien moet ik het inderdaad in twee stappen gaan doen.

Inmiddels heb ik het bijna voor elkaar om het deel vanaf "Lees meer:"/"Lees ook:" te pakken en dan daarna alle linkjes die erachter staan. M'n huidige regexp ziet er als volgt uit:

PHP:
1
$regexp = '%(Lees ook:|Lees meer:).*?((<a.*?href=[\'|"].*?[\'|"].*?>.*?</a>).*?)+%mis';


Probleem hierbij is alleen dat het hyperlink-gedeelte niet wordt herhaald. Na één keer houdt hij ermee op. Deze regexp heeft overigens standaard dus greedy op "aan" staan, alleen in de meeste .* constructies gebruik ik daarbij de extra ? om greedyness naar laziness te zetten.

preg_match_all geeft dan alleen de "Lees meer:" met vervolgens de eerste link. Daarna houdt hij ermee op.

EDIT:
Hmmm ... deze is een stuk makkelijker te lezen:
PHP:
1
$regexp = '%(Lees ook:).*?(?:.*?(<a.*?</a>))+%isu';


Deze pakt precies de goede string. Alleen doordat het herhalende laatste deel wordt backreference 2 steeds overschreven, waardoor ik niets kan met link 1 en 2, want alleen de laatste link (3) wordt bewaard.

[ Voor 18% gewijzigd door gvanh op 29-11-2007 11:35 ]

Pagina: 1