Non-breaking whitespace (MySQL): verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
(6 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
[[file:20191201-0548.png|thumb|Dit is het probleem: De eerste spatie is geen gewone spatie (<code>0x20</code>), maar ''NBSP'' (''Non-breaking whitespace''): <code>0xc2a0</code>. Hoe fix ik dat?]]
+
[[file:20191201-0548.png|thumb|Dit leek het initiële probleem te zijn: De eerste spatie is geen gewone spatie (<code>0x20</code>), maar ''NBSP'' (''Non-breaking whitespace''): <code>0xc2a0</code>. Hoe fix ik dat?]]
Tijdens verwerken van een UTF-8 import-bestand in MySQL, leek het alsof MySQL spaties niet herkende (Dec. 2019). Uiteindelijk bleken de betreffende strings geen gewone spaties te bevatten (<code>20</code>), maar ''Non-breaking white spaces'' (<code>c2 a0</code>).
 
  
* Hoe herken je NBSP in strings?
+
Tijdens verwerken van een UTF-8-import-bestand in MySQL (dec. 2019), bleken sommige spaties geen echte spaties te zijn, maar ''non-breaking whitespace'' (of zoiets - zie verderop). Daardoor kon ik die data niet zomaar verwerken, omdat sommige algorithmes ervan uitgingen, dat spaties eh, spaties zijn.
* Hoe vervang je NBSP voor gewone spaties?
 
  
== Niet ==
+
* Hoe herken je NBSP (of andere afwijkende 'spaties') in strings?
 +
* Hoe vervang je NBSP (of andere afwijkende 'spaties') door gewone spaties?
  
=== Regular expressions ===
+
== Het probleem: Een spatie is niet een spatie ==
  
Filteren mbv. ASCII-codes in regular expressions, lijkt niet zomaar te werken:
+
Er bleken twee problemen te zijn:
 +
 
 +
=== NBSP? ===
 +
 
 +
Het gaat om een handjevol records in een bepaalde tabel: De betreffende strings bleken geen gewone spaties te bevatten (<code>20</code>), maar ''Non-breaking white spaces'' (<code>c2 a0</code>). Zie de afbeelding bovenaan dit artikel.
 +
 
 +
=== Iets anders? ===
 +
 
 +
Als ik de betreffende string omfiets naar hex, krijg ik alleen ''a0'', en niet de andere byte. Ik snap niet hoe dat kan.
 +
 
 +
== De oplossing ==
 +
 
 +
Toegevoegd aan de importroutine voor dit bestand:
  
 
<pre>
 
<pre>
select device_sku from device_tmp
+
update tmp
where
+
set
device_sku regexp "\x42";
+
  device_id_org_source     = replace(device_id_org_source,   unhex("a0"), " "),
 +
  device_voltage_org_source = replace(device_voltage_org_source, unhex("a0"), " "),
 +
  device_sku     = replace(device_sku,   unhex("a0"), " ");
 
</pre>
 
</pre>
 
Ongetwijfeld kunnen regular expressions overweg met karaktercodering, maar dit lijkt niet de manier te zijn (met <code>\\\</code> lukt 't ook niet).
 
  
 
== Bronnen ==
 
== Bronnen ==
Regel 25: Regel 36:
 
* https://stackoverflow.com/questions/41939514/find-non-breaking-space-in-mysql
 
* https://stackoverflow.com/questions/41939514/find-non-breaking-space-in-mysql
 
* https://www.w3resource.com/mysql/string-functions/mysql-unhex-function.php
 
* https://www.w3resource.com/mysql/string-functions/mysql-unhex-function.php
 +
* http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=A0&mode=hex

Versie van 1 dec 2019 10:12

Dit leek het initiële probleem te zijn: De eerste spatie is geen gewone spatie (0x20), maar NBSP (Non-breaking whitespace): 0xc2a0. Hoe fix ik dat?

Tijdens verwerken van een UTF-8-import-bestand in MySQL (dec. 2019), bleken sommige spaties geen echte spaties te zijn, maar non-breaking whitespace (of zoiets - zie verderop). Daardoor kon ik die data niet zomaar verwerken, omdat sommige algorithmes ervan uitgingen, dat spaties eh, spaties zijn.

  • Hoe herken je NBSP (of andere afwijkende 'spaties') in strings?
  • Hoe vervang je NBSP (of andere afwijkende 'spaties') door gewone spaties?

Het probleem: Een spatie is niet een spatie

Er bleken twee problemen te zijn:

NBSP?

Het gaat om een handjevol records in een bepaalde tabel: De betreffende strings bleken geen gewone spaties te bevatten (20), maar Non-breaking white spaces (c2 a0). Zie de afbeelding bovenaan dit artikel.

Iets anders?

Als ik de betreffende string omfiets naar hex, krijg ik alleen a0, en niet de andere byte. Ik snap niet hoe dat kan.

De oplossing

Toegevoegd aan de importroutine voor dit bestand:

update tmp
set
   device_id_org_source	     = 	replace(device_id_org_source, 	   unhex("a0"), " "),
   device_voltage_org_source =	replace(device_voltage_org_source, unhex("a0"), " "),
   device_sku		     =	replace(device_sku, 		   unhex("a0"), " ");

Bronnen