跳到正文
DEV Community· Emir Mrkaljević·· 3 小時前AI 評分38

ShrinkWatch EU 如何辨識 20 多種歐盟語言的單價標籤

Grundpreis, jämförpris, egységár: reading unit prices on shops in 20+ EU languages

AI 導讀

開源瀏覽器擴充功能 ShrinkWatch EU 會按商品包裝規格和價格計算單價,再與商店標示的單價交叉核對,並辨識 20 多種歐盟語言的標籤。文章列出各語言的單價和件數用詞,以及避免誤判的規則;程式碼採用 MIT 授權,擴充功能不會自行發出網絡請求,只讀取用戶正在瀏覽的頁面。

正文

EU law (directive 98/6/EC) says shops must show a unit price: the price per kilo, per litre or per piece. Every country calls it something different, and every shop prints it a little differently. My open-source browser extension ShrinkWatch EU computes the unit price itself from the pack size and price, then cross-checks it against the shop's own figure. To do that cross-check it has to find the shop's figure first.

This post is the list of words I ended up matching, and the small traps behind them.

The label words

The shop's own unit price usually sits next to a label. These are the ones the extension reads today:

Language Label
German Grundpreis, Literpreis, Kilopreis
French prix au kg, prix au litre, prix unitaire
Italian prezzo al kg, prezzo al litro, prezzo unitario
Spanish precio por kg, precio por litro, precio unitario
Portuguese preço por kg, preço por litro
Dutch prijs per kilo, prijs per liter, eenheidsprijs
Croatian / Bosnian cijena za kg, cijena za j.m., jedinična cijena
Polish cena jednostkowa, cena za kg
Czech jednotková cena
Hungarian egységár
Romanian preț unitar, preț pe kg
Swedish jämförpris
Norwegian / Danish kilopris, literpris, enhedspris
Finnish yksikköhinta, kilohinta

All of it is one case-insensitive regex anchored to the start of the label, so "Grundpreis" matches but a product called "Kilopreis-Knaller" in a title does not get treated as a label.

Piece counts

Eggs, rolls and coffee capsules are priced per piece. Each language has its own abbreviation, and most of them are two or three letters:

szt, sztuk (PL)  ks, kusů (CZ, SK)  db, darab (HU)  buc, bucăți (RO)
stuks, stuk (NL)  pz, pezzi (IT)  uds, unidades (ES)  un, unid (PT)
pièce, pièces (FR)  st, styck (SE)  stk, styk (DK, NO)  kpl (FI)
tk (EE)  vnt (LT)  gab (LV)  τεμ (GR)  бр (BG)  kom (HR, BA, RS)

Short words are dangerous. "db" is also the start of plenty of Polish words, "tk" shows up inside other text, and "1st" in English is an ordinal, not one Swedish piece ("st"). The rules that keep this safe: the unit must follow a number, must not be followed by another letter, and "1st" without a space is skipped. So "10 db" is ten pieces, while "dbałość" and "1st Grade Apples" are ignored.

The second rule: weight or volume beats a piece count. "Kawa kapsułki 10 szt. 52 g" is a 52 g pack, priced per kilo, not per capsule. People compare coffee by weight, and shrinkflation usually hides in the grams.

The third rule: when a product has no weight or volume at all, pack-count phrases such as "10er Pack", "12-pack", "12-p", "pack of 10", "lot de 12", "boîte de 10" or "confezione da 10" count as pieces. That is how Irish, German, Swedish, French and Italian shops usually title egg boxes.

Three decimals and decimal commas

The bug that cost me the most time was this one: Mercadona prints "1,367 €/L". My price regex expected at most two decimals, so it skipped the "1," and happily matched "367 €/L" in the middle of the figure. The cross-check then showed 367 euros per litre. The fix was to require that the number starts the figure (no digit or comma right before it) and to accept up to three decimals, because no supermarket sells milk at hundreds of euros a litre.

Why bother

France (since July 2024) and Hungary already make shops flag shrinkflation on the shelf. Everywhere else, the unit price is the only tool shoppers have, and it is often printed in small grey type. Reading it reliably in every language is the boring part that makes everything else work.

The code is MIT licensed and has no network requests of its own: it only reads the page you are looking at. If your shop prints its unit price with a word not in this list, open an issue with the product link and I will add it.

This article was written with AI assistance. The code, tests and examples come from the repo.

來源:DEV Community · dev.to