Vraag


Acties:
  • 0 Henk 'm!

  • Reckless1976
  • Registratie: Mei 2018
  • Laatst online: 11-11-2023
Ik ben bezig automatisch gegenereerde berichten te verwerken, een deel van deze berichten bevatten loacties van snelwegen of provicenale wegen. Deze wil ik graag filteren, verwerken een locatie aan vast hangen.
Ik ben geen expert in het maken van scripts en heb al het nodige geprobeerd maar dit is waar ik op uit kom.
Onderstaande geeft echter nog te veel false positives.
Wie wil en kan mij hiermee helpen?

Berichten komen binnen en een deel van de berichten zullen er ongeveer zo uit zien:
" A10 Re - Ringweg-West Amsterdam" of " A15 Li 49,2 Hoogvliet Rotterdam" of " A20 Re Rotterdam" of "N14 Re - Noordelijke Randweg 14,6 Leidschendam"

Het script wat dicht in buurt komt is:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
regex_snelweg = r"\s([A][0-9].) (Re)|\s([A][0-9].) (Li)"
snelw = re.search(regex_snelweg, message)  
if snelw:
    snelweg = snelw.group(1)
    richting = snelw.group(2)
    if city:
        address = (f"{snelweg} {city}")
    else:
        address = (f"{snelweg}")
regex_snelweg = r"\s([N][0-9].) (Re)|\s([N][0-9].) (Li)"
snelw = re.search(regex_snelweg, message)  
if snelw:
    snelweg = snelw.group(1)
    richting = snelw.group(2)
    if city:
        address = (f"{snelweg} {city}")
    else:
        address = (f"{snelweg}")


De plaatsbepaling (city) is al vooraf bepaald.
De volgende stap zal worden de locatiebepaling dmv de HMP (indien aanwezig) eruit te halen.
Als je mij hiermee op het juiste pad kan zetten, heel graag.

Beste antwoord (via Reckless1976 op 14-10-2023 17:47)


  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 09:19
Dat gebeurt enkel als je niet Ascii zoals bijvoorbeeld utf-8 of unicode binnenkrijgt en dan nog zijn dat dan gewoon digits en niet iets vreemds.

Tegenwoordig schrijf je juist code die unicode "aware" is.

Zoiets is een goede aanzet.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

MSG_REG = re.compile(r".?(?P<Type>A|N)(?P<Road>\d{1,3})\s?(?P<Direction>Re|Li)?")

Msg = [" A10 Re - Ringweg-West Amsterdam",
       " A15 Li 49,2 Hoogvliet Rotterdam",
       " A20 Re Rotterdam",
       "N14"]

for Item in Msg:
    if Resp := MSG_REG.match(Item):    
        Info = Resp.groupdict()
    else:
        Info = "Unkown format"
    print(Info)

[ Voor 51% gewijzigd door Ben(V) op 11-10-2023 10:50 ]

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.

Alle reacties


Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Geef eens een paar false positives?
Je kan trouwens beter `[1-9][0-9]*` gebruiken ipv `[0-9].`

[ Voor 3% gewijzigd door Juup op 05-10-2023 16:21 ]

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 10:01

Knutselsmurf

LED's make things better

Een beetje IDE heeft vaak ook wel de optie voor een RegEx-plugin. Voer daar je gebruikte RegEx in en een false positive, en je krijgt feedback over de wijze waarop de match is gemaakt. Vaak helpt dat bij het herkennen van de fout in de RegEx

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • Reckless1976
  • Registratie: Mei 2018
  • Laatst online: 11-11-2023
Juup schreef op donderdag 5 oktober 2023 @ 16:20:
Geef eens een paar false positives?
De false positives geven een None in group(1). Waardoor mijn address bijv. [None Rotterdam] is geworden.
Natuurlijk kan ik dit weer met een "if-functie" blokkeren maar dat lijk mij niet DE oplossing.
Je kan trouwens beter `[1-9][0-9]*` gebruiken ipv `[0-9].`
Dan mis ik toch de bijvoorbeeld snelweg A1 tm A9?

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Reckless1976 schreef op donderdag 5 oktober 2023 @ 16:43:
De false positives geven een None in group(1). Waardoor mijn address bijv. [None Rotterdam] is geworden.
Natuurlijk kan ik dit weer met een "if-functie" blokkeren maar dat lijk mij niet DE oplossing.
Geef ons anders een paar voorbeelden
Dan mis ik toch de bijvoorbeeld snelweg A1 tm A9?
Nee, `*` betekent 0 of meer keer.

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 10:01

Knutselsmurf

LED's make things better

Reckless1976 schreef op donderdag 5 oktober 2023 @ 16:43:
[...]


De false positives geven een None in group(1). Waardoor mijn address bijv. [None Rotterdam] is geworden.
Natuurlijk kan ik dit weer met een "if-functie" blokkeren maar dat lijk mij niet DE oplossing.
Maar wat was dan de input waar de None uitkwam? Dit lijkt op een false negative. Je verwacht een match, maar die wordt niet gevonden. Een false positive is een match die wel wordt gevonden, terwijl je dat juist niet verwacht.

Je Regex `\s([A][0-9].)` is te lezen als :
- begin van de tekst
- dan de letter A
- dan een cijfer 0-9
- dan een (1) willekeurig teken

A2A dan hier dus mee matchen (niet goed)
A25 zal ook matchen (goed)
A325 zal niet matchen (niet goed)

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • Reckless1976
  • Registratie: Mei 2018
  • Laatst online: 11-11-2023
Het aanpassen van de Regex in `[1-9][0-9]*' werkt inderdaad beter.
Ben er achter gekomen dat de 'or-functie' in de Regex niet goed werkt.
Wanneer ik dmv een 'if not functie' maak die een nieuwe Regex aanroept gaat het wel goed.
Weet iemand waarom de "|" niet als OR werkt?
mijn code is nu:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
regex_snelweg = r"\s([A][1-9][0-9]*) (Re)"
snelw = re.search(regex_snelweg, message)  
if not snelw:
    regex_snelweg = r"\s([A][1-9][0-9]*) (Li)"
    snelw = re.search(regex_snelweg, message) 
if snelw:
    snelweg = snelw.group(1)
    richting = snelw.group(2)
    if snelweg:
        if city:
            address = (f"{snelweg} {city}")
        else:
            address = (f"{snelweg}")
regex_snelweg = r"\s([N][1-9][0-9]*) (Re)"
snelw = re.search(regex_snelweg, message)  
if not snelw:
    regex_snelweg = r"\s([N][1-9][0-9]*) (Li)"
    snelw = re.search(regex_snelweg, message)
if snelw:
    snelweg = snelw.group(1)
    richting = snelw.group(2)
    if snelweg:
        if city:
            address = (f"{snelweg} {city}")
        else:
            address = (f"{snelweg}")


Ik heb bewust de snelweg en de rijksweg uit elkaar gehouden, maar kan dit niet makkelijker?
Kan ik ook een apparte groep bijvoegen voor de HMP die soms tussen de A of N-weg staat en de Li of Re of vaker achter de richting? Zodat ik de HMP ook isoleer indien aanwezig.

[ Voor 67% gewijzigd door Reckless1976 op 08-10-2023 16:58 ]


Acties:
  • +2 Henk 'm!

  • SPee
  • Registratie: Oktober 2001
  • Laatst online: 11-09 15:48
Reckless1976 schreef op zondag 8 oktober 2023 @ 16:36:
Het aanpassen van de Regex in `[1-9][0-9]*' werkt inderdaad beter.
Ben er achter gekomen dat de 'or-functie' in de Regex niet goed werkt.
Wanneer ik dmv een 'if not functie' maak die een nieuwe Regex aanroept gaat het wel goed.
Weet iemand waarom de "|" niet als OR werkt?
Volgens mij komt dat omdat de OR niet over de gehele regex gaat, maar alleen het laatste stukje dat gematcht is. En dat is dan "(Re)|\s([A][0-9].)"
Dus als je het gehele stuk ervoor als één blok wil matchen, dan moet je die grouperen.

Ik zou overigens de regex zoiets maken: ((A|N)[0-9]+) (Li|Re)?


spoiler:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. :+

let the past be the past.


Acties:
  • +1 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 15:45
Wanneer je met regex werkt, is het handig om een tool zoals https://regex101.com te gebruiken. Hiermee kun je je regex zichtbaar maken en het debuggen aanzienlijk vergemakkelijken.

Acties:
  • 0 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 09:19
In plaats van [0-9] kun je betere \d{1,3} gebruiken.

Ofwel 1 t/m 3 digits

[ Voor 5% gewijzigd door Ben(V) op 11-10-2023 09:43 ]

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 15:45
Ben(V) schreef op woensdag 11 oktober 2023 @ 09:43:
In plaats van [0-9] kun je betere \d{1,3} gebruiken.

Ofwel 1 t/m 3 digits
Daar moet je erg mee oppassen. De definitie van \d verschilt namelijk erg per regex implementatie, of de meegegeven regex opties. In een aantal implementaties, zoals bijvoorbeeld Python, Rust, C, .NET, betekent \d standaard namelijk ieder unicode decimal digit. Dat is veel meer dan enkel [0-9], en kan dus ongewenste resultaten opleveren.

Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 09:19
Dat gebeurt enkel als je niet Ascii zoals bijvoorbeeld utf-8 of unicode binnenkrijgt en dan nog zijn dat dan gewoon digits en niet iets vreemds.

Tegenwoordig schrijf je juist code die unicode "aware" is.

Zoiets is een goede aanzet.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

MSG_REG = re.compile(r".?(?P<Type>A|N)(?P<Road>\d{1,3})\s?(?P<Direction>Re|Li)?")

Msg = [" A10 Re - Ringweg-West Amsterdam",
       " A15 Li 49,2 Hoogvliet Rotterdam",
       " A20 Re Rotterdam",
       "N14"]

for Item in Msg:
    if Resp := MSG_REG.match(Item):    
        Info = Resp.groupdict()
    else:
        Info = "Unkown format"
    print(Info)

[ Voor 51% gewijzigd door Ben(V) op 11-10-2023 10:50 ]

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


Acties:
  • 0 Henk 'm!

  • Reckless1976
  • Registratie: Mei 2018
  • Laatst online: 11-11-2023
Bedankt voor jullie bijdrage, Ik ben er goed mee geholpen.
Pagina: 1