WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Word boundary i reguljära uttryck (https://www.wn.se/forum/showthread.php?t=36162)

koala 2009-04-07 00:28

\b är ju smidigt i reguljära uttryck när man vill matcha hela ord (t ex: /\bord\b/). Tyvärr funkar det inte alltid så bra med annat än engelska ord (\w) bestående av [a-zA-Z0-9]. Ord som innehåller svenska tecken delas upp felaktigt, t ex "innehåller", som blir "\binneh\bå\bller". Detta ställer till det en del för mig både i PHP och JavaScript, och jag undrar om någon annan har smidiga lösningar?

Exempelkod (JavaScript eftersom det är vad jag håller på med just nu, men jag får motsvarande i PHP):

Kod:

"de det de öde både ödem <b>öde</b> <b>de</b> öde".replace(/\bde\b/gi, '--')

Resultat: "-- det -- ö-- bå-- ödem <b>ö--</b> <b>--</b> ö--"
Önskat resultat: "-- det -- öde både ödem <b>öde</b> <b>--</b> öde"

Är det någon som har smidiga förslag på sätt att ställa in vad \b (och \w) ska matcha i PHP samt JavaScript? De workarounds jag använt inkluderar dels att splitta strängen vid " " men det känns lite klumpigt i jämförelse med ett enkelt \b, och löser inte heller allt (t ex missar man ju ord som avslutas med punkt eller en HTML-tagg).

emilv 2009-04-07 07:50

[^a-zåäöA-ZÅÄÖ0-9] kanske? Inte lika smidigt, men du kanske kan lägga det i en variabel?

Magnus_A 2009-04-07 09:29

Om diakriter räknas som del av ord borde styras av locale-inställningarna för php tycker man.

martine 2009-04-07 11:12

Citat:

Originally posted by Magnus_A@Apr 7 2009, 09:29
Om diakriter räknas som del av ord borde styras av locale-inställningarna för php tycker man.
Kan man tycka men det verkar som den gängse åsikten är att \b ska match:a [a-z] och inget annat (för bakåtkompabilitet).

Enklaste lösningen är att använda lösningar med \pL och andra unicode (utf-8) klasser. Framförallt bör man avhålla sig från att använda emilvs bristfälliga lösning (tar bara med ett fåtal undantag - missar exempelvis é).

koala 2009-04-13 18:41

Som kuriosa kan nämnas att i Python kan man ganska lätt få locale-inställningarna att styra över detta.

martine 2009-04-13 19:59

Citat:

Originally posted by koala@Apr 13 2009, 18:41
Som kuriosa kan nämnas att i Python kan man ganska lätt få locale-inställningarna att styra över detta.
Intressant. Känns dock som det inte är så optimalt att förändra hur ett regexp fungerar med locale-inställningar.

Bättre vore ju om det skulle fungera med \b för alla ord, alltid. Även på engelska betraktas ju ord som naïve och crème som ord även om dom har tecken som gör medelamerikanen förvirrad. Dessutom skulle väl även en amerikan betrakta ett grekiskt ord som just ett ord även fast dom inte kunde läsa det…?

Dessvärre är väl detta som vanligt en rest på vägen från ascii via iso-8859 till unicode. Hursomhelst så fungerar ju \pL för alla bokstäver och det är väl lösningen.

Som ytterligare kuriosa kan tilläggas att Perl, som var populärt innan det så avancerade asp och det så praktiska php, har utmärkt regexp-stöd för unicode.

koala 2009-04-15 22:50

Citat:

Originally posted by martine@Apr 13 2009, 19:59
Intressant. Känns dock som det inte är så optimalt att förändra hur ett regexp fungerar med locale-inställningar.
Kanske inte det bästa, men man lägger bara till en extra flagga till reguljära uttryck om man vill att de ska påverkas av locale-inställningen, och vill man ha bakåtkompatibilitet så skippar man det. Känns som en ganska pragmatisk lösning, som jag skulle önska kunde göras även i JavaScript på något sätt.

Kod:

# python:
re.L
re.LOCALE
  Make \w, \W, \b, \B, \s and \S dependent on the current locale.


martine 2009-04-16 11:29

Citat:

Originally posted by koala@Apr 15 2009, 22:50
Kanske inte det bästa, men man lägger bara till en extra flagga till reguljära uttryck om man vill att de ska påverkas av locale-inställningen, och vill man ha bakåtkompatibilitet så skippar man det. Känns som en ganska pragmatisk lösning, som jag skulle önska kunde göras även i JavaScript på något sätt.
Nja, jag är nog fortfarande skeptisk. Om man följer locale-inställningarna så tas ju éåäö med som svenska bokstäver men vad händer med orden "müsli" och "à"…? Och vilken teckenkodning förutsätter man?

För javascript vore i alla fall en sådan lösning rena katastrofen - alla webbläsare skulle implementera det lite annorlunda - och vara beroende av klientens språkinställningar (vilka kan råka eller inte råka vara samma språk som språket på webbsidan)! (Vilket gör att när du surfar in på dn från webbkaféet i Peking så får du kinesiska locale-inställningar…).

Nä, lösningen är förstås att använda unicode-baserade teckenklasser som redan finns i exempelvis Perl och php. Javascript är dessutom baserat på unicode så att använda en u-flagga som i php exempelvis vore långt mycket bättre. Kika lite på t.ex. \p{Separator}, \p{Letter} och \p{Greek} om du missat detta.

koala 2009-04-16 20:51

Ja, unicodebaserade teckenklasser är nog prima, i PHP i alla fall. Tackar för det tipset martine.

Men i JavaScript funkar väl inte \p{Separator} etc? Jag har i alla fall aldrig sett något om att JavaScript skulle stödja det.

martine 2009-04-17 04:00

Citat:

Originally posted by koala@Apr 16 2009, 20:51
Men i JavaScript funkar väl inte \p{Separator} etc? Jag har i alla fall aldrig sett något om att JavaScript skulle stödja det.
Nej, tråkigt nog så finns det tyvärr inget stöd för detta i JavaScript. Vi lär nog få vänta många år på det eftersom regexp i JavaScript just nu inte verkar vara särskilt prioriterat - och när förbättringar väl kommer så kommer det väl först till en eller ett par webbläsare (sannolikt inte först till den mest använda, Explorer)…

Så än så länge så har du inget annat val än att själv "deklarera" klasserna (som tur är så är i alla fall JavaScript unicodebaserat så det ska inte bli något trubbel där) med hjälp av gamla hederliga [aáàäå…] eller kanske lite enklare \uXXXX-\uXXXX.


Alla tider är GMT +2. Klockan är nu 16:01.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson