[RegExp] Hulp nodig bij complexe RegularExpression

Pagina: 1
Acties:

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Hoi iedereen,

Ik zou graag gebruik maken van een complexe reguliere expressie in de rules van mijn (Usenet) nieuwsclient Microplanet Gravity. Dat heeft niet meteen iets met programmeren te maken, maar reguliere expressies op zich zijn al een halve programmeertaal. Vandaar ook dat ik m'n vraag hier stel. Over Gravity zelf hoef ik niets te weten.

Wat is de bedoeling?
De reguliere expressie moet zoeken op het voorkomen van mijn naam in de nieuwsberichten zodat ik niet alle berichten (van groepen waarin vaak meer dan 1000 berichten per dag bijkomen) moet lezen. Dat is erg eenvoudig natuurlijk:

RegExp: wimvde

Maar er zijn ook mensen die m'n site in hun signature hebben staan. Ik wil dus niet dat al die berichten 'gewatcht' worden in Gravity. Enkel wanneer mijn naam in het bericht zelf voorkomt. De signature moet dus genegeerd worden. Dat is relatief eenvoudig omdat een signature steeds met '-- ' of '--' (in het geval van crappy Outlook Express) begint. Je krijgt dan iets in de aard van:

RegExp: --(.)*www\.provider\.be/wimvde

Maar het wordt nog complexer. Als iemand een reply op mij doet dan kan het voorkomen (maar niet noodzakelijk), dat het bericht begint met "WimVDE wrote:" of "In article blah blah WimVDE wrote",... Deze berichten dienen logischerwijs niet gewatcht te worden.

Hoe los je dat op?

En als icing op de cake, dient het voorkomen van mijn naam in quotes (>) ook genegeerd te worden. Dus enkel in het bericht zelf. Voor één regel is dat makkelijk te maken met een reguliere expressie, maar hoe pas je dat toe doorheen een heel bericht?

Hieronder enkele simpele voorbeeldjes:
In bericht blah schreef "WimVDE"

> zomaar wat bladvulling om het gewenste duidelijk
> te maken aan de lezers van deze thread. Dit is
> de quote van het bericht waarin WimVDE voorkomt.

En meer bladvulling. Het eigenlijke antwoord.

--
Leuke site: http://www.provider.be/wimvde/
Dit mag dus geen match zijn, ondanks dat WimVDE driemaal voorkomt. Maar hetvolgende voorbeeld:
WimVDE schreef op deze dag:

> zomaar wat bladvulling om het gewenste duidelijk
> te maken aan de lezers van deze thread. Dit is
> de quote van het bericht.
> de quote van het bericht waarin WimVDE voorkomt.

En meer bladvulling. Het eigenlijke antwoord. Nu
staat er wel WimVDE in het eigenlijke bericht.

--
Leuke site: http://www.provider.be/wimvde/
Dit moet wel een match opleveren... Ik zit nu al enkele uren te knoeien met reguliere expressies, maar krijg er niets deftigs uit. Is het uberhaupt wel mogelijk met een reguliere expressie?

Alvast bedankt voor enige tips :)

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Bij dit soort dingen moet je altijd de regels zo duidelijk mogelijk opstellen.

• wimvde mag niet gematcht worden als het een internetadres is
• Ook niet als er 'wrote:' o.i.d. achterstaat
• Of als het replied is en er dus een > voorstaat.

Dus wordt het iets als: (uitgaande van PCRE-regural expressions)
code:
1
(?!www\.provider\.be/|>.*)wimvde(?!.*wrote:)

Dit zal waarschijnlijk niet helemaal werken, maar het moet wel iets in die richting zijn. Daarnaast moet je ook nog oppassen of jouw regular expression engine per newline werkt of niet.

Succes ermee!

  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Ah, die reguliere expressies zijn schijnbaar nog uitgebreider dan ik dacht :)
Ik moet dringend eens een uitgebreider boek daarover kopen (ik lees nu de summiere uitleg erover in O'Reilly's "Learning Perl").

Alvast bedankt voor de tips. Ik ga vannacht weer eens wat overuurtjes maken denk ik :P

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
code:
1
(?!www\.provider\.be/|>.*)wimvde(?!.*wrote:)

Die newline schijnt me wel tegen te zitten. Blijkbaar parsed Gravity de hele tekst als een doorlopende string.

Bijvoorbeeld als ik onderstaande reguliere expressie gebruik

RegExp: >.*wimvde

Dan matcht hij op:
> zomaar wat bladvulling om het gewenste duidelijk
> te maken aan de lezers van deze thread.
> Hier komt WimVDE in voor.
Maar evengoed op
> zomaar wat bladvulling om het gewenste duidelijk
> te maken aan de lezers van deze thread.

Hier staat WimVDE niet achter het quote teken
Wat dus niet de bedoeling is van die kleine reguliere expressie. Dus ik moet nog iets uitvissen om rekening te kunnen houden met linebreaks.

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
We komen dichter. Nu kan ik al matchen in een quote:

RegExp: >[^\n]*Wimvde

(in mijn implementatie moet het natuurlijk net andersom)

[ Voor 6% gewijzigd door mahi op 23-02-2004 14:14 ]

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Leuke monoloog die ik hier aan het starten ben ;)

Ik ben weeral ietsje verder, maar nog niet ver genoeg :)
Het blijkt dat Gravity de hele body van een bericht parsed als 1 string. De regelafbrekingen gebeuren door een \n karakter.

Dus, ik had al:

RegExp: --.*www\.provider\.be/wimvde

Dat matcht op het voorkomen van mijn website in iemands signature. Nu is het de bedoeling dat dit omgekeerd wordt. Er mag geen match zijn wanneer mijn site voorkomt in iemand's signature. Hoe pak ik dat aan bij een reguliere expressie? Voor een enkel karakter weet ik dat de negatie gebeurt met het ^-teken, maar hoe zit het met een groep zoals bovenstaande voorbeeld? "elnino" schijnt daarvoor ?! te gebruiken, of is dat iets anders? En kan ik dat er gewoon voorzetten want dat schijnt niet veel effect te hebben.

Nu om ervoor te zorgen dat er niet gematcht wordt op gequote text heb ik volgende expressie:

RegExp: \n[^>][^\n]*wimvde

Die \n staat er om Gravity duidelijk te maken dat een quote (>) steeds aan het begin van een regel begint. Dit om misverstanden te vermijden bij het vermelden van een url bijvoorbeeld (<url:http://www.site.be/>). De [^>] wijst erop dat aan het begin van de regel _geen_ '>' quote-teken mag voorkomen (er mag geen match zijn in de quote). Om er nu voor te zorgen dat er niet gematcht wordt op volgende situatie:
> zomaar wat bladvulling om het gewenste duidelijk
> te maken aan de lezers van deze thread.
> En WimVDE staat nu in het quoteblok

Antwoord blah blah
Staat er ook [^\n]* wat betekent dat er na de quote geen linebreak mag voorkomen. Anders zou na het parsen van 'de eerste regel' meteen doorgegaan worden met de andere regels tot het voorkomen van WimVDE. De [^\n]* zorgt er dus voor dat alles lijn per lijn gebeurt.

Dat werkt dus uitstekend. Maar hoe pas ik het aan zodat er wel een match is als WimVDE voorkomt in het eigenlijke bericht? Ik zou denken:

RegExp: \n[^>]?[^\n]*wimvde

De [^>]? zou er volgens mij voor moeten zorgen dat:
> En WimVDE staat nu in het quoteblok
Geen match geeft, en
En nu staat WimVDE in het eigenlijke antwoord
Wel een match geeft. Of ben ik mis? Maar dat schijnt dus niet te werken :(

(dat m'n naam ook in de eerste regels kan voorkomen in het geval van een reply laat ik nog eventjes buiten beschouwing - eerst alles stap voor stap implementeren)

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Nog wat verder, maar nog steeds niet zoals het moet. Ik heb al;

RegExp: \n[^>][^\n]*wimvde

Dat zorgt er dus voor dat:
> De quote van het artikel waarin WimVDE
> vermeld wordt.
Geen match geeft, maar:
> De quote van het artikel.

Het eigenlijke artikel waarin WimVDE
voorkomt.
Wel matcht.

En volgende regular expression

RegExp: \n(--[^-].*){0}wimvde

Zorgt ervoor dat signatures waarin m'n naam voorkomt ook geen match geven:
> Dit is de quote van het artikel
> waarin WimVDE voorkomt. Hier wordt
> niet op gematcht

Het antwoord komt hier te staan
--
Dit is de signature met een link
http://www.provider.be/wimvde
Op bovenstaand voorbeeld wordt (correct) niet gematcht door de laatst gegeven regular expression, ongeacht er tweemaal WimVDE in voorkomt.

Dus nu is het de bedoeling om beide regular expressions samen te voegen, maar daar schijn ik toch nogal wat problemen mee te hebben. Ik voeg ze samen als:

RegExp: \n([^>][^\n]*wimvde|(--[^-].*){0}wimvde)

Maar omdat de eerste regular expression term ([^>][^\n]*wimvde) matcht bij het voorkomen van WimVDE in alle zinnen zolang er geen '>' quotingsteken voorstaat, matcht deze ook in de signature. Dus de tweede term heeft geen effect meer.

Hoe los ik dat op?

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.


  • mahi
  • Registratie: Juni 2001
  • Laatst online: 03-10-2025

mahi

God bless GoT

Topicstarter
Niemand? :'(

A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.

Pagina: 1