[PHP / REGEX] Preg_match stad + land uit elkaar trekken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Na lang stoeien toch maar besloten mijn probleem met jullie te delen. Ik ben erg dichtbij gekomen, maar het lukt me net niet.

Momenteel ben ik bezig een MSSQL-tabel met gebruikergegevens (NL & BE) te converteren naar een MySQL-tabel, en ik probeer meteen zoveel mogelijk data via een PHP-script op te schonen of te splitsen naar verschillende velden.

Momenteel loop ik vast bij het veld 'city', waar onze zuiderburen vaak iets als "Brussel, België" ingevuld hebben.

Ik probeer nu met een regex het volgende voor elkaar te krijgen:

Brussel (België) => Group 2: Brussel, Groep 3: België
Antwerpen [Belgie) => Group 2: Antwerpen, Groep 3: Belgie
Brussel, belgië => Group 2: Brussel, Groep 3: België
Brussel (BELGIE => Group 2: Brussel, Groep 3: Belgie
deurne,belgie => Group 2: deurn, Group 3: belgie

Ik ben een heel eind gekomen met de volgende regex:
PHP:
1
^(([\w\W]+)+(?:[, ]+)?\(\[?(België|Belgie|belgie|belgië)\)\]?)$


Maar ik heb nu nog het probleem dat de komma in de capturing group terecht komt.
Op de een of andere manier heb ik altijd ruzie met regex-en, dus ik zal wel weer iets heel simpels of stoms verkeerd doen.. maar wat?

Overigens check ik verderop in m'n script of Groep 3 gevuld is met iets. Zoja, dan ga ik er vanuit dat het om een Belgisch-persoon gaat.

Acties:
  • 0 Henk 'm!

Verwijderd

Als je nou ten eerste eens je regex case-insensitive maakt (#expressie#i), dan hoef je je om hoofdletters/kleine letters al niet meer druk te maken. Scheelt weer. ;)

Verder is je expressie sowieso nogal messy. Een word die 1 of meer keer moet voorkomen, die vervolgens weer 1 of meer keer moet voorkomen? Beetje dubbel. ;)

Als laatste zou ik gewoon 2 keer preg_match() erop los laten. Eentje voor haakjes, en de andere voor komma's. Kun je je regex's lekker eenvoudig houden, en aangezien bij een (eenmalige?) conversie performance nou niet echt een top issue is, waarom niet?

Acties:
  • 0 Henk 'm!

  • masq
  • Registratie: September 2004
  • Laatst online: 18-04 00:18
code:
1
[\w\W]+


Dit is behoorlijk zinloos, toch? Had net zo goed dit kunnen staan:

code:
1
.+


Daardoor wordt je komma opgegeten (de komma groep is immers toch optional).

Verder

code:
1
\(\[?


dus de [ is optioneel maar de ( niet?

tenslotte nog een suggestie:

code:
1
belgi[eë]
(iets korter ;) )

Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Op een of andere manier heb ik erg veel moeie met denken in regex. Ook als ik het stap voor stap probeer in elkaar te draaien. Dus .. messy kan kloppen :S.

Het 'i'-tje voor case insensitive is toegevoegd. Stuk handiger ja.

2x preg_match kan ook natuurlijk. Performance is inderdaad geen issue.

Wat betreft de reactie van masq.
Ik zie idd wat onlogische dingen nu.
Heb nu:
code:
1
/^((.+)(?:[, ]+)?\(?\[?(belgi[ë|e])\)?\]?)$/i


Hierbij is het komma probleem nog niet opgelost. Hoe zorg ik ervoor dat die niet 'opgegeten' wordt, en dat alleen 'belgië' in een group komt?

Acties:
  • 0 Henk 'm!

Verwijderd

.+ vervangen door [^,]+ waardoor die alles behalve komma's matcht.

Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Verwijderd schreef op maandag 10 augustus 2009 @ 17:13:
.+ vervangen door [^,]+ waardoor die alles behalve komma's matcht.
Probleem dan is dat hij helemaal niet meer matched.
Hoe krijg ik het dan wel in de juiste groep?

Dus bijv.
Brussel, Belgie => Groep 1: Brussel, Groep 2: Belgie

Wel matchen, maar niet in een groep gooien dus.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wolf3D schreef op maandag 10 augustus 2009 @ 17:07:
Op een of andere manier heb ik erg veel moeie met denken in regex.
* RobIII wijst maar weer eens naar Creepy's signature...
Waarom een regex?

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


Acties:
  • 0 Henk 'm!

Verwijderd

Wolf3D schreef op maandag 10 augustus 2009 @ 17:25:
[...]


Probleem dan is dat hij helemaal niet meer matched.
Hoe krijg ik het dan wel in de juiste groep?

Dus bijv.
Brussel, Belgie => Groep 1: Brussel, Groep 2: Belgie

Wel matchen, maar niet in een groep gooien dus.
Niet moeilijk doen gewoon een explode gebruiken ;)

PHP:
1
2
3
4
5
6
7
8
9
10
<?php

$geheel = 'Brussel, Belgie';

$groepen = explode(', ', $geheel);

$groep1 = $groepen['0']; // Brussel
$groep2 = $groepen['1']; // Belgie

?>

Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Tja, ik wil het waarschijnlijk weer te mooi inderdaad.

Ik heb het nu zo opgelost:

PHP:
1
2
3
$value = str_replace(","," ", $value);
$pattern = "/^(([^,]+) \(?\[?(belgi[ë|e])\)?\]?)$/i";
preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE);


Werkt ook prima. Bedankt voor jullie hulp!

Acties:
  • 0 Henk 'm!

  • estherdg
  • Registratie: Oktober 2006
  • Laatst online: 21-12-2021

estherdg

nubcake

hey, het viel me op dat jouw uiteindelijke regex niet helemaal doet wat jij wilt, k heb er zelf even één gemaakt en getest.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

$string = "Brussel (België)
Antwerpen [Belgie)
Brussel, belgië 
Brussel (BELGIE 
deurne,belgie ";


$pattern = "/([^, \t\r\n\v\f]*).*\(?\[?(belgi[ë|e])\)?/i";

preg_match_all($pattern,$string,$matches);

var_dump($matches);


dit komt eruit:

array(3) {
[0]=>
array(5) {
[0]=>
string(16) "Brussel (België)"
[1]=>
string(18) "Antwerpen [Belgie)"
[2]=>
string(15) "Brussel, belgië"
[3]=>
string(15) "Brussel (BELGIE"
[4]=>
string(13) "deurne,belgie"
}
[1]=>
array(5) {
[0]=>
string(7) "Brussel"
[1]=>
string(9) "Antwerpen"
[2]=>
string(7) "Brussel"
[3]=>
string(7) "Brussel"
[4]=>
string(6) "deurne"
}
[2]=>
array(5) {
[0]=>
string(6) "België"
[1]=>
string(6) "Belgie"
[2]=>
string(6) "belgië"
[3]=>
string(6) "BELGIE"
[4]=>
string(6) "belgie"
}
}

misschien is dat meer wat jij wilt?
Pagina: 1