euredact 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +262 -13
- package/dist/cjs/cloud/client.js +7 -4
- package/dist/cjs/rules/countries/index.js +125 -42
- package/dist/cjs/rules/cues.js +21 -2
- package/dist/cjs/rules/suppressors.js +130 -5
- package/dist/cjs/rules/validators.js +53 -0
- package/dist/cjs/sdk.js +133 -38
- package/dist/esm/cloud/client.d.ts +7 -4
- package/dist/esm/cloud/client.js +7 -4
- package/dist/esm/rules/countries/index.js +125 -42
- package/dist/esm/rules/cues.d.ts +13 -1
- package/dist/esm/rules/cues.js +21 -2
- package/dist/esm/rules/suppressors.js +130 -5
- package/dist/esm/rules/validators.js +53 -0
- package/dist/esm/sdk.d.ts +12 -15
- package/dist/esm/sdk.js +133 -38
- package/package.json +1 -1
|
@@ -28,6 +28,41 @@ function p(entityType, pattern, validator = null, description = "", contextKeywo
|
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
// Secret context keywords (consolidated, reused across SECRET patterns)
|
|
30
30
|
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Words that name a travel document, in the official languages of the 31
|
|
33
|
+
* countries this engine covers, plus English.
|
|
34
|
+
*
|
|
35
|
+
* Shared by every passport pattern. Before this existed each country kept its
|
|
36
|
+
* own list, so a passport was only recognised when its shape and its label
|
|
37
|
+
* came from the same country: `Reisepass: CA1234567` was missed because the
|
|
38
|
+
* German pattern rejects that alphabet while the Dutch pattern, whose shape
|
|
39
|
+
* fits, had never heard of "Reisepass" (issue rules-engine#23).
|
|
40
|
+
*
|
|
41
|
+
* The bare Scandinavian "pass", Finnish "passi" and Latvian "pase" are
|
|
42
|
+
* omitted deliberately: context matching is substring, not word-boundary, so
|
|
43
|
+
* they fire inside "password", "passenger", "passive" and "phase". Only the
|
|
44
|
+
* compound forms are listed. Mirrors PASSPORT_CONTEXT in Python.
|
|
45
|
+
*/
|
|
46
|
+
const PASSPORT_CONTEXT = [
|
|
47
|
+
"passport", "passport no", "passport number", "travel document",
|
|
48
|
+
"reisepass", "passnummer", "reisepassnummer", "reisepass-nr", "pass nr",
|
|
49
|
+
"reisedokument",
|
|
50
|
+
"paspoort", "paspoortnummer", "reisdocument", "identiteitsbewijs",
|
|
51
|
+
"passeport", "numéro de passeport", "document de voyage",
|
|
52
|
+
"passaporto", "numero di passaporto", "documento di viaggio",
|
|
53
|
+
"pasaporte", "número de pasaporte", "documento de viaje",
|
|
54
|
+
"passaporte", "número do passaporte",
|
|
55
|
+
"passnr", "passets nummer", "passin numero", "passinumero",
|
|
56
|
+
"passi number", "passinumber",
|
|
57
|
+
"vegabréf", "vegabréfsnúmer",
|
|
58
|
+
"paso numeris", "pases numurs",
|
|
59
|
+
"paszport", "numer paszportu", "cestovní pas", "číslo pasu",
|
|
60
|
+
"cestovný pas", "potni list", "številka potnega lista",
|
|
61
|
+
"putovnica", "broj putovnice",
|
|
62
|
+
"útlevél", "útlevélszám", "pașaport", "numărul pașaportului",
|
|
63
|
+
"паспорт", "номер на паспорт", "διαβατήριο",
|
|
64
|
+
"αριθμός διαβατηρίου", "passaport",
|
|
65
|
+
];
|
|
31
66
|
const SECRET_CONTEXT = [
|
|
32
67
|
// English
|
|
33
68
|
"key", "token", "secret", "password", "credential",
|
|
@@ -67,18 +102,50 @@ const SECRET_CONTEXT = [
|
|
|
67
102
|
// ---------------------------------------------------------------------------
|
|
68
103
|
// DOB context keywords (reused across SHARED patterns)
|
|
69
104
|
// ---------------------------------------------------------------------------
|
|
105
|
+
// Every way the documents this engine sees introduce a date of birth.
|
|
106
|
+
//
|
|
107
|
+
// DOB recall was 62.8% -- 33,441 unmasked birth dates -- because this covered
|
|
108
|
+
// seven languages of thirty-one. Eleven countries scored exactly 100% (the
|
|
109
|
+
// listed languages) while twenty sat at 42-51%, which is what proved it was
|
|
110
|
+
// coverage rather than capability (rules-engine#38).
|
|
111
|
+
//
|
|
112
|
+
// Matching is substring, not word-boundary, so every entry was screened against
|
|
113
|
+
// the 29.2-million-character corpus for occurrences inside a longer word. Two
|
|
114
|
+
// were rejected: `fædd` lives inside `fæddur`, and `born` was found inside
|
|
115
|
+
// `gabornagy` and `gabornemeth` -- Hungarian names as e-mail local parts -- so
|
|
116
|
+
// `"born "` with the trailing space is listed instead.
|
|
117
|
+
//
|
|
118
|
+
// DOB_CONTEXT is gone: it was a second, shorter copy missing `nato il`,
|
|
119
|
+
// `nascido`, `geburtstag` and more, so ISO dates were gated on fewer keywords
|
|
120
|
+
// than DD/MM/YYYY ones for no stated reason.
|
|
70
121
|
const DOB_CONTEXT = [
|
|
122
|
+
// Germanic / Romance -- the original set, kept verbatim.
|
|
71
123
|
"geboren", "geboortedatum", "date de naissance", "né le", "née le",
|
|
72
124
|
"né(e) le", "nee le", "nee(e) le", "date of birth", "DOB",
|
|
73
125
|
"Geburtsdatum", "geboren am", "geboren op", "nascido", "nacido",
|
|
74
126
|
"data di nascita", "nato il", "nata il", "geb.", "geb.datum", "geb ",
|
|
75
127
|
"birth date", "birthday", "naissance", "geboorte", "geburtstag",
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
128
|
+
// English and Italian forms the list was missing.
|
|
129
|
+
"born ", "d.o.b", "nato/a il",
|
|
130
|
+
// Nordic.
|
|
131
|
+
"født", "fødselsdato", "född", "födelsedatum",
|
|
132
|
+
"syntynyt", "syntymäaika", "fæddur", "fæðingardagur",
|
|
133
|
+
// Greek -- Greece and Cyprus.
|
|
134
|
+
"γεννηθείς", "γεννήθηκε", "ημερομηνία γέννησης",
|
|
135
|
+
// West Slavic.
|
|
136
|
+
"urodzony", "urodzona", "data urodzenia",
|
|
137
|
+
"narozen", "datum narození", "narodený", "dátum narodenia",
|
|
138
|
+
// Hungarian, Romanian, Bulgarian.
|
|
139
|
+
"született", "születési", "născut", "născută", "data nașterii",
|
|
140
|
+
"роден", "родена", "дата на раждане",
|
|
141
|
+
// South Slavic.
|
|
142
|
+
"rođen", "rođena", "datum rođenja", "rojen", "rojena", "datum rojstva",
|
|
143
|
+
// Baltic.
|
|
144
|
+
"sündinud", "sünniaeg", "dzimis", "dzimusi", "dzimšanas datums",
|
|
145
|
+
"gimęs", "gimusi", "gimimo data",
|
|
146
|
+
// Maltese, Irish, Turkish (Cyprus).
|
|
147
|
+
"twieled", "twieldet", "data tat-twelid",
|
|
148
|
+
"rugadh", "dáta breithe", "doğum tarihi",
|
|
82
149
|
];
|
|
83
150
|
const DATE_OF_DEATH_CONTEXT = [
|
|
84
151
|
"overleden", "overlijdensdatum", "date de décès", "décédé le",
|
|
@@ -118,6 +185,17 @@ const SHARED = {
|
|
|
118
185
|
// "Call (+32 475 12 34 56) today." also masked the ")" (issue
|
|
119
186
|
// rules-engine#3). Mirrors the Python pattern character for character.
|
|
120
187
|
p(EntityType.PHONE, String.raw `\+\d{1,3}(?:[\s\-/]?(?:\(\d{1,4}\)|\d{1,4})){2,7}`, "e164", "International phone number (E.164) — any country"),
|
|
188
|
+
// Passport (any country). The per-country patterns cover BE, DE, FR and NL
|
|
189
|
+
// only; the other 26 had none. Same argument as the E.164 phone rule: one
|
|
190
|
+
// country-independent shape, with the label carrying the precision.
|
|
191
|
+
// Shapes from the project canon (prompts/pii_definitions.md, PASSPORT):
|
|
192
|
+
// EU is 1-2 letters + 7 digits, UK is 9 digits optionally GBR-prefixed.
|
|
193
|
+
// The canon's position is that the EU converged on one shape, so national
|
|
194
|
+
// regexes would contradict it as well as being unverifiable. An earlier
|
|
195
|
+
// draft required a leading letter and missed all-numeric passports, the
|
|
196
|
+
// UK's own format among them; requiring exactly nine digits for the
|
|
197
|
+
// numeric form rejects eight-digit dates on shape (issue rules-engine#23).
|
|
198
|
+
p(EntityType.PASSPORT, String.raw `\b(?:GBR\d{9}|[A-Z]{1,2}\d{7}|\d{9})\b`, null, "Passport number — any country, label-gated", PASSPORT_CONTEXT, true),
|
|
121
199
|
p(EntityType.BIC, String.raw `\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b`, "bic"),
|
|
122
200
|
// Space-separated form: "RZBA AT WW", "NICA BE BB". Written as a separate
|
|
123
201
|
// pattern requiring a space between *every* group, rather than making the
|
|
@@ -174,7 +252,12 @@ const SHARED = {
|
|
|
174
252
|
// --- Secret / API Key (connection strings with embedded credentials) ---
|
|
175
253
|
p(EntityType.SECRET, String.raw `(?:mongodb|mysql|postgres(?:ql)?|redis|amqp|rabbitmq):\/\/[^\s:]{1,256}:[^\s@]{1,256}@[^\s]+`, null, "Connection string with credentials"),
|
|
176
254
|
// --- Secret / API Key (assignment-based: KEY=value or KEY: value) ---
|
|
177
|
-
|
|
255
|
+
// The final character may not be sentence punctuation. `\S` does not stop
|
|
256
|
+
// at a full stop, so "Reisepass: CA1234567." was claimed as the
|
|
257
|
+
// ten-character span "CA1234567." -- a passport number plus the sentence's
|
|
258
|
+
// period, masked as a credential because a "credentials" word sat within
|
|
259
|
+
// the context window (rules-engine#35).
|
|
260
|
+
p(EntityType.SECRET, String.raw `(?<=[:=] )\S{7,}[^\s.,;:!?)'"]|(?<=[:=])\S{7,}[^\s.,;:!?)'"]`, "high_entropy", "Assigned secret value", SECRET_CONTEXT, true),
|
|
178
261
|
// --- Secret / API Key (entropy-based fallback for longer tokens) ---
|
|
179
262
|
// Only the *trailing* \b is replaced. It could not match when the token run
|
|
180
263
|
// ended on "-", "+" or "/", so the engine backtracked across two
|
|
@@ -192,7 +275,7 @@ const SHARED = {
|
|
|
192
275
|
p(EntityType.SECRET, String.raw `\b[A-Za-z0-9_\-+/]{24,}[A-Za-z0-9_\-+/=]*(?![A-Za-z0-9_\-+/=])`, "high_entropy", "High-entropy token", SECRET_CONTEXT, true),
|
|
193
276
|
p(EntityType.DOB, String.raw `\b(?:0[1-9]|[12][0-9]|3[01])[/.\-](?:0[1-9]|1[0-2])[/.\-](?:19|20)\d{2}\b`, null, "DD/MM/YYYY", DOB_CONTEXT, true),
|
|
194
277
|
p(EntityType.DATE_OF_DEATH, String.raw `\b(?:0[1-9]|[12][0-9]|3[01])[/.\-](?:0[1-9]|1[0-2])[/.\-](?:19|20)\d{2}\b`, null, "", DATE_OF_DEATH_CONTEXT, true),
|
|
195
|
-
p(EntityType.DOB, String.raw `\b(?:19|20)\d{2}[/.\-](?:0[1-9]|1[0-2])[/.\-](?:0[1-9]|[12][0-9]|3[01])\b`, null, "ISO YYYY-MM-DD",
|
|
278
|
+
p(EntityType.DOB, String.raw `\b(?:19|20)\d{2}[/.\-](?:0[1-9]|1[0-2])[/.\-](?:0[1-9]|[12][0-9]|3[01])\b`, null, "ISO YYYY-MM-DD", DOB_CONTEXT, true),
|
|
196
279
|
],
|
|
197
280
|
};
|
|
198
281
|
const NL = {
|
|
@@ -202,7 +285,7 @@ const NL = {
|
|
|
202
285
|
p(EntityType.NATIONAL_ID, String.raw `\b[0-9]{9}\b`, "bsn"),
|
|
203
286
|
p(EntityType.NATIONAL_ID, String.raw `\b[0-9]{2,4}\.[0-9]{2,4}\.[0-9]{2,4}\b`, "bsn"),
|
|
204
287
|
p(EntityType.IBAN, String.raw `\bNL\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?\d{2}\b`, "iban"),
|
|
205
|
-
p(EntityType.VAT, String.raw `\bNL\d{9}B\d{2}\b`, "vat_nl"),
|
|
288
|
+
p(EntityType.VAT, String.raw `\bNL[\s.]?\d{9}B\d{2}\b`, "vat_nl"),
|
|
206
289
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b\d{8}\b`, "kvk", "", ["KvK", "Kamer van Koophandel", "kvk-nummer", "KVK-nummer", "handelsregister", "chamber of commerce"], true),
|
|
207
290
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d[\s\-]?\d{3}[\s\-]?\d{4}\b`),
|
|
208
291
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d{2}[\s\-]?\d{6,7}\b`),
|
|
@@ -211,7 +294,7 @@ const NL = {
|
|
|
211
294
|
p(EntityType.PHONE, String.raw `\b06[\s\-]?\d{2}[\s\-]?\d{2}[\s\-]?\d{2}[\s\-]?\d{2}\b`),
|
|
212
295
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d{1,2}[\s\-]?\d{2,3}[\s\-]?\d{2}[\s\-]?\d{2}\b`),
|
|
213
296
|
p(EntityType.PHONE, String.raw `\+31\s?[1-9]\d{0,2}[\s\-]?\d{3,4}[\s\-]?\d{3,4}\b`),
|
|
214
|
-
p(EntityType.PASSPORT, String.raw `\b[A-Z][A-Z0-9]{8}\b`, null, "",
|
|
297
|
+
p(EntityType.PASSPORT, String.raw `\b[A-Z][A-Z0-9]{8}\b`, null, "", PASSPORT_CONTEXT, true),
|
|
215
298
|
p(EntityType.LICENSE_PLATE, String.raw `\b(?:[A-Z]{2}[\-\s]?\d{3}[\-\s]?[A-Z]|\d[\-\s]?[A-Z]{3}[\-\s]?\d{2}|\d{2}[\-\s]?[A-Z]{3}[\-\s]?\d|[A-Z]{2}[\-\s]?\d{2}[\-\s]?[A-Z]{2}|\d{2}[\-\s]?[A-Z]{2}[\-\s]?\d{2}|\d[\-\s]?[A-Z]{2}[\-\s]?\d{3})\b`),
|
|
216
299
|
p(EntityType.POSTAL_CODE, String.raw `\b[1-9]\d{3}\s?[A-Z]{2}\b`),
|
|
217
300
|
],
|
|
@@ -226,10 +309,10 @@ const BE = {
|
|
|
226
309
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b0\d{3}\.?\d{3}\.?\d{3}\b`, null, "", ["KBO", "BCE", "ondernemingsnummer", "numéro d'entreprise", "enterprise number", "bedrijfsnummer", "Kruispuntbank", "Banque-Carrefour", "Banque Carrefour", "Ondernemingen", "Entreprises", "onder nummer"], true),
|
|
227
310
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d{0,2}[/\s.\-]?\d{2,3}[.\s\-]?\d{2,3}[.\s\-]?\d{2,3}\b`),
|
|
228
311
|
p(EntityType.PHONE, String.raw `\+32\s?\d{1,3}[\s.\-]?\d{2,3}[\s.\-]?\d{2}[\s.\-]?\d{2}`),
|
|
229
|
-
p(EntityType.PASSPORT, String.raw `\b[A-Z]{2}\d{6}\b`, null, "",
|
|
312
|
+
p(EntityType.PASSPORT, String.raw `\b[A-Z]{2}\d{6}\b`, null, "", PASSPORT_CONTEXT, true),
|
|
230
313
|
p(EntityType.DRIVERS_LICENSE, String.raw `\b\d{10}\b`, null, "", ["rijbewijs", "permis de conduire", "driving licence", "driving license", "rijbewijsnummer"], true),
|
|
231
314
|
p(EntityType.LICENSE_PLATE, String.raw `\b[12][\-\s]?[A-Z]{3}[\-\s]?\d{3}\b`),
|
|
232
|
-
p(EntityType.POSTAL_CODE, String.raw `\b[1-9]\d{3}\b`, null, "", ["postcode", "code postal", "postnummer", "postal code", "zip", "B-", "adres", "adresse", "wonende", "woonplaats", "rue", "straat", "laan", "avenue", "boulevard", "plein", "steenweg", "chaussée", "domicilié", "gedomicilieerd", "Levering:", "siège"], true),
|
|
315
|
+
p(EntityType.POSTAL_CODE, String.raw `\b[1-9]\d{3}\b`, null, "", ["postcode", "code postal", "postnummer", "postal code", "zip", "B-", "adres", "adresse", "wonende", "woonplaats", "domicile", "rue", "straat", "laan", "avenue", "boulevard", "plein", "steenweg", "chaussée", "domicilié", "gedomicilieerd", "Levering:", "siège"], true),
|
|
233
316
|
p(EntityType.POSTAL_CODE, String.raw `(?<=, )[1-9]\d{3}(?= [A-Z])`),
|
|
234
317
|
p(EntityType.HEALTHCARE_PROVIDER, String.raw `\b\d{1}[\-.]?\d{5}[\-.]?\d{2}[\-.]?\d{3}\b`, null, "", ["RIZIV", "INAMI", "arts", "médecin", "zorgverlener", "prestataire", "dokter", "doctor"], true),
|
|
235
318
|
],
|
|
@@ -245,7 +328,7 @@ const DE = {
|
|
|
245
328
|
p(EntityType.VAT, String.raw `\bDE\s?\d{9}\b`, "vat_de"),
|
|
246
329
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d{1,4}[\s/\-]?\d{3,8}\b`),
|
|
247
330
|
p(EntityType.PHONE, String.raw `\+49\s?\d{2,5}[\s/\-]?\d{3,8}\b`),
|
|
248
|
-
p(EntityType.PASSPORT, String.raw `\b[CFGHJK][0-9CFGHJKLMNPRTVWXYZ]{8}\d?\b`, null, "",
|
|
331
|
+
p(EntityType.PASSPORT, String.raw `\b[CFGHJK][0-9CFGHJKLMNPRTVWXYZ]{8}\d?\b`, null, "", PASSPORT_CONTEXT, true),
|
|
249
332
|
// The separator after the city code is mandatory. When it was optional, a
|
|
250
333
|
// contiguous letter run split across both groups and the hyphen was
|
|
251
334
|
// consumed as the *second* separator, so any "LETTERS-DIGITS" token
|
|
@@ -254,7 +337,7 @@ const DE = {
|
|
|
254
337
|
// separates the city code: "B-AB 1234", "M-XY 99".
|
|
255
338
|
p(EntityType.LICENSE_PLATE, String.raw `\b[A-ZÄÖÜ]{1,3}[\s\-][A-Z]{1,2}[\s\-]?\d{1,4}[EH]?\b`),
|
|
256
339
|
p(EntityType.POSTAL_CODE, String.raw `\b\d{5}\b`, null, "", ["PLZ", "Postleitzahl", "postal code", "postcode", "Anschrift", "Adresse", "Wohnort", "Ort", "Stadt", "wohnt", "wohnhaft", "Straße", "Str.", "Weg", "Platz", "Allee", "Ring"], true),
|
|
257
|
-
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\bHR[AB]\s?\d{4,6}\b
|
|
340
|
+
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\bHR[AB]\s?\d{4,6}(?:\s[A-Z]\b)?`),
|
|
258
341
|
p(EntityType.SSN, String.raw `\b\d{2}[\s]?\d{6}[\s]?[A-Z][\s]?\d{3}\b`, null, "", ["Rentenversicherung", "RV-Nummer", "Sozialversicherung", "SV-Nummer", "Versicherungsnummer", "Rentenversicherungsnummer", "Sozialversicherungsnummer", "SVNR", "SV-Nr", "RVNR"], true),
|
|
259
342
|
p(EntityType.TAX_ID, String.raw `\b\d{2,3}/\d{3,4}/\d{4,5}\b`, null, "", ["Steuernummer", "St.-Nr", "StNr", "Finanzamt", "Steuer"], true),
|
|
260
343
|
p(EntityType.TAX_ID, String.raw `\b\d{13}\b`, null, "", ["Steuernummer", "St.-Nr", "StNr", "Finanzamt", "Steuer"], true),
|
|
@@ -267,7 +350,7 @@ const AT = {
|
|
|
267
350
|
patterns: [
|
|
268
351
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{4}\s?\d{6}\b`, "austrian_svnr"),
|
|
269
352
|
p(EntityType.IBAN, String.raw `\bAT\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
270
|
-
p(EntityType.VAT, String.raw `\bATU\d{8}\b`),
|
|
353
|
+
p(EntityType.VAT, String.raw `\bATU[\s.]?\d{8}\b`),
|
|
271
354
|
p(EntityType.PHONE, String.raw `\b0\d{3,4}[\s\-]?\d{5,8}\b`),
|
|
272
355
|
// Short area codes (Vienna is "01") split across three groups:
|
|
273
356
|
// "01 53460 2215". The pattern above requires 3-4 digits after the trunk
|
|
@@ -306,9 +389,9 @@ const FR = {
|
|
|
306
389
|
p(EntityType.VAT, String.raw `\bFR\s?[0-9A-HJ-NP-Z]{2}\s?\d{9}\b`, "vat_fr"),
|
|
307
390
|
p(EntityType.PHONE, String.raw `\b0[1-9][\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}\b`),
|
|
308
391
|
p(EntityType.PHONE, String.raw `\+33\s?[1-9][\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}`),
|
|
309
|
-
p(EntityType.PASSPORT, String.raw `\b\d{2}[A-Z]{2}\d{5}\b`, null, "",
|
|
392
|
+
p(EntityType.PASSPORT, String.raw `\b\d{2}[A-Z]{2}\d{5}\b`, null, "", PASSPORT_CONTEXT, true),
|
|
310
393
|
p(EntityType.LICENSE_PLATE, String.raw `\b[A-Z]{2}[\-\s]?\d{3}[\-\s]?[A-Z]{2}\b`),
|
|
311
|
-
p(EntityType.POSTAL_CODE, String.raw `\b(?:0[1-9]|[1-8]\d|9[0-5]|97[1-6])\d{3}\b`, null, "", ["code postal", "CP", "postal code", "postcode", "adresse", "domicilié", "résidant", "rue", "avenue", "boulevard", "place", "chemin", "allée", "impasse", "ville"], true),
|
|
394
|
+
p(EntityType.POSTAL_CODE, String.raw `\b(?:0[1-9]|[1-8]\d|9[0-5]|97[1-6])\d{3}\b`, null, "", ["code postal", "CP", "postal code", "postcode", "adresse", "domicile", "domicilié", "résidant", "rue", "avenue", "boulevard", "place", "chemin", "allée", "impasse", "ville"], true),
|
|
312
395
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b\d{3}\s?\d{3}\s?\d{3}\b`, null, "", ["SIREN", "siren", "RCS", "entreprise", "immatricul", "numéro d'entreprise", "registre du commerce"], true),
|
|
313
396
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b\d{3}\s?\d{3}\s?\d{3}\s?\d{5}\b`, null, "", ["SIRET", "siret", "établissement", "immatricul"], true),
|
|
314
397
|
p(EntityType.TAX_ID, String.raw `\b\d{13}\b`, null, "", ["numéro fiscal", "SPI", "référence fiscale", "avis d'impôt", "impôt sur le revenu", "déclaration fiscale", "fiscal"], true),
|
|
@@ -341,9 +424,9 @@ const SE = {
|
|
|
341
424
|
p(EntityType.PHONE, String.raw `\b0\d{1,3}[\-\s]?\d{2,3}[\s]?\d{2,3}[\s]?\d{2}\b`),
|
|
342
425
|
p(EntityType.PHONE, String.raw `\+46\s?\d{1,3}[\s\-]?\d{2,3}[\s\-]?\d{2,3}[\s\-]?\d{2}`),
|
|
343
426
|
p(EntityType.LICENSE_PLATE, String.raw `\b[A-Z]{3}\s?\d{2}[A-Z0-9]\b`),
|
|
344
|
-
p(EntityType.POSTAL_CODE, String.raw `\b\d{3}\s?\d{2}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé", "plats", "torg", "stigen", "Bostadsadress"], true),
|
|
345
|
-
p(EntityType.POSTAL_CODE, String.raw `\b\d{4}\s\d{2}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé"], true),
|
|
346
|
-
p(EntityType.POSTAL_CODE, String.raw `\b\d{6}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé"], true),
|
|
427
|
+
p(EntityType.POSTAL_CODE, String.raw `\b\d{3}\s?\d{2}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "Postal:", "Address:", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé", "plats", "torg", "stigen", "Bostadsadress"], true),
|
|
428
|
+
p(EntityType.POSTAL_CODE, String.raw `\b\d{4}\s\d{2}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "Postal:", "Address:", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé"], true),
|
|
429
|
+
p(EntityType.POSTAL_CODE, String.raw `\b\d{6}\b`, null, "", ["postnummer", "postort", "postkod", "adress", "Postal:", "Address:", "bostadsadress", "gatuadress", "boende", "gatan", "vägen", "gata", "väg", "allé"], true),
|
|
347
430
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b\d{6}-?\d{4}\b`, null, "", ["organisationsnummer", "org.nr", "org nr", "Bolagsverket", "registreringsnummer"], true),
|
|
348
431
|
],
|
|
349
432
|
};
|
|
@@ -359,7 +442,7 @@ const NO = {
|
|
|
359
442
|
p(EntityType.PHONE, String.raw `\b[2-9]\d\s?\d{2}\s?\d{2}\s?\d{2}\b`),
|
|
360
443
|
p(EntityType.PHONE, String.raw `\+47\s?\d{2}\s?\d{2}\s?\d{2}\s?\d{2}`),
|
|
361
444
|
p(EntityType.LICENSE_PLATE, String.raw `\b[A-Z]{2}\s?\d{5}\b`),
|
|
362
|
-
p(EntityType.POSTAL_CODE, String.raw `\b\d{4}\b`, null, "", ["postnummer", "poststed", "postnr", "adresse", "bostedsadresse", "gate", "vei", "veien", "gata", "plass", "stien", "allé"], true),
|
|
445
|
+
p(EntityType.POSTAL_CODE, String.raw `\b\d{4}\b`, null, "", ["postnummer", "poststed", "postnr", "adresse", "bostedsadresse", "gate", "vei", "veien", "gata", "plass", "stien", "allé", "Postal:", "Address:"], true),
|
|
363
446
|
],
|
|
364
447
|
};
|
|
365
448
|
const FI = {
|
|
@@ -368,7 +451,7 @@ const FI = {
|
|
|
368
451
|
patterns: [
|
|
369
452
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{6}[-+ABCDEFYXWVU]\d{3}[0-9A-FHJK-NPR-Y]\b`, "finnish_hetu"),
|
|
370
453
|
p(EntityType.IBAN, String.raw `\bFI\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}\b`, "iban"),
|
|
371
|
-
p(EntityType.VAT, String.raw `\bFI\d{8}\b`),
|
|
454
|
+
p(EntityType.VAT, String.raw `\bFI[\s.]?\d{8}\b`),
|
|
372
455
|
p(EntityType.CHAMBER_OF_COMMERCE, String.raw `\b\d{7}-\d\b`, "finnish_business_id"),
|
|
373
456
|
p(EntityType.PHONE, String.raw `\b0\d{1,2}\s?\d{3,4}\s?\d{3,4}\b`),
|
|
374
457
|
p(EntityType.PHONE, String.raw `\+358\s?\d{1,3}[\s\-]?\d{3,4}[\s\-]?\d{3,4}`),
|
|
@@ -386,7 +469,7 @@ const IS = {
|
|
|
386
469
|
p(EntityType.PHONE, String.raw `\b[3-9]\d{6}\b`, null, "", ["sími", "símanúmer", "farsími", "gsm", "phone", "tel", "hringja", "hringdu", "ná í", "nás á", "nás", "SMS", "sent to"], true),
|
|
387
470
|
p(EntityType.PHONE, String.raw `\+354\s?\d{3}\s?\d{4}`),
|
|
388
471
|
p(EntityType.LICENSE_PLATE, String.raw `\b[A-Z]{2}\s?\d{3}\b`, null, "", ["skráningarnúmer", "bílnúmer", "ökutæki", "bifreið", "plata"], true),
|
|
389
|
-
p(EntityType.POSTAL_CODE, String.raw `\b[1-9]\d{2}\b`, null, "", ["póstnúmer", "póstfang", "staður", "heimilisfang"], true),
|
|
472
|
+
p(EntityType.POSTAL_CODE, String.raw `\b[1-9]\d{2}\b`, null, "", ["póstnúmer", "póstfang", "staður", "heimilisfang", "Postal:", "Address:"], true),
|
|
390
473
|
],
|
|
391
474
|
};
|
|
392
475
|
const IT = {
|
|
@@ -396,7 +479,7 @@ const IT = {
|
|
|
396
479
|
p(EntityType.NATIONAL_ID, String.raw `\b[A-Z]{6}\d{2}[ABCDEHLMPRST]\d{2}[A-Z]\d{3}[A-Z]\b`, "italian_cf"),
|
|
397
480
|
p(EntityType.IBAN, String.raw `\bIT\d{2}\s?[A-Z]\d{3}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}\b`, "iban"),
|
|
398
481
|
p(EntityType.IBAN, String.raw `\bIT\d{2}[A-Z]\d{22}\b`, "iban"),
|
|
399
|
-
p(EntityType.VAT, String.raw `\bIT\d{11}\b`),
|
|
482
|
+
p(EntityType.VAT, String.raw `\bIT[\s.]?\d{11}\b`),
|
|
400
483
|
p(EntityType.PHONE, String.raw `\b3\d{2}[\s\-]?\d{3}[\s\-]?\d{4}\b`),
|
|
401
484
|
p(EntityType.PHONE, String.raw `\b0\d{1,3}[\s\-]?\d{6,8}\b`),
|
|
402
485
|
p(EntityType.PHONE, String.raw `\b0\d{1,2}[\s\-]\d{3}[\s\-]\d{4}\b`),
|
|
@@ -412,7 +495,7 @@ const ES = {
|
|
|
412
495
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{8}[A-Z]\b`, "spanish_dni"),
|
|
413
496
|
p(EntityType.NATIONAL_ID, String.raw `\b[XYZ]\d{7}[A-Z]\b`, "spanish_nie"),
|
|
414
497
|
p(EntityType.IBAN, String.raw `\bES\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
415
|
-
p(EntityType.VAT, String.raw `\bES[A-Z0-9]\d{7}[A-Z0-9]\b`),
|
|
498
|
+
p(EntityType.VAT, String.raw `\bES[\s.]?[A-Z0-9]\d{7}[A-Z0-9]\b`),
|
|
416
499
|
p(EntityType.PHONE, String.raw `\b[679]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
417
500
|
p(EntityType.PHONE, String.raw `\b[679]\d{8}\b`),
|
|
418
501
|
p(EntityType.PHONE, String.raw `\b[679]\d[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}\b`),
|
|
@@ -435,7 +518,7 @@ const PT = {
|
|
|
435
518
|
p(EntityType.NATIONAL_ID, String.raw `\b[1-35-9]\d{8}\b`, "portuguese_nif"),
|
|
436
519
|
p(EntityType.NATIONAL_ID, String.raw `\b[1-35-9]\d{2}[\s.]\d{3}[\s.]\d{3}\b`, "portuguese_nif"),
|
|
437
520
|
p(EntityType.IBAN, String.raw `\bPT\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{5}\b`, "iban"),
|
|
438
|
-
p(EntityType.VAT, String.raw `\bPT\d{9}\b`),
|
|
521
|
+
p(EntityType.VAT, String.raw `\bPT[\s.]?\d{9}\b`),
|
|
439
522
|
p(EntityType.PHONE, String.raw `\b[29]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
440
523
|
p(EntityType.PHONE, String.raw `\b[29]\d{8}\b`),
|
|
441
524
|
p(EntityType.PHONE, String.raw `\+351\s?[29]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}`),
|
|
@@ -468,7 +551,7 @@ const PL = {
|
|
|
468
551
|
p(EntityType.TAX_ID, String.raw `\b\d{3}-?\d{3}-?\d{2}-?\d{2}\b`, "polish_nip"),
|
|
469
552
|
p(EntityType.IBAN, String.raw `\bPL\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
470
553
|
p(EntityType.IBAN, String.raw `\bPL\d{26}\b`, "iban"),
|
|
471
|
-
p(EntityType.VAT, String.raw `\bPL\d{10}\b`),
|
|
554
|
+
p(EntityType.VAT, String.raw `\bPL[\s.]?\d{10}\b`),
|
|
472
555
|
p(EntityType.PHONE, String.raw `\b[5-8]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
473
556
|
p(EntityType.PHONE, String.raw `\b[5-8]\d{8}\b`),
|
|
474
557
|
p(EntityType.PHONE, String.raw `\+48\s?[5-8]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}`),
|
|
@@ -482,7 +565,7 @@ const IE = {
|
|
|
482
565
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{7}[A-W][ABWTXZ]?\b`, "irish_pps"),
|
|
483
566
|
p(EntityType.IBAN, String.raw `\bIE\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}\b`, "iban"),
|
|
484
567
|
p(EntityType.IBAN, String.raw `\bIE\d{2}[A-Z]{4}\d{14}\b`, "iban"),
|
|
485
|
-
p(EntityType.VAT, String.raw `\bIE\d{7}[A-Z]\b`),
|
|
568
|
+
p(EntityType.VAT, String.raw `\bIE[\s.]?\d{7}[A-Z]\b`),
|
|
486
569
|
p(EntityType.PHONE, String.raw `\b0[89]\d[\s\-]?\d{3}[\s\-]?\d{4}\b`),
|
|
487
570
|
p(EntityType.PHONE, String.raw `\b0[89]\d{8}\b`),
|
|
488
571
|
p(EntityType.PHONE, String.raw `\b0[1-9]\d{0,2}[\s\-]?\d{5,8}\b`),
|
|
@@ -498,7 +581,7 @@ const UK = {
|
|
|
498
581
|
p(EntityType.HEALTH_INSURANCE, String.raw `\b\d{3}\s?\d{3}\s?\d{4}\b`, "uk_nhs", "", ["NHS", "NHS number", "health number", "NHS no"], true),
|
|
499
582
|
p(EntityType.IBAN, String.raw `\bGB\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}\b`, "iban"),
|
|
500
583
|
p(EntityType.IBAN, String.raw `\bGB\d{2}[A-Z]{4}\d{14}\b`, "iban"),
|
|
501
|
-
p(EntityType.VAT, String.raw `\bGB\d{
|
|
584
|
+
p(EntityType.VAT, String.raw `\bGB[\s.]?\d{3}[\s.]?\d{4}[\s.]?\d{2}\b`),
|
|
502
585
|
p(EntityType.PHONE, String.raw `\b07[4-9]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
503
586
|
p(EntityType.PHONE, String.raw `\b07[4-9]\d{8}\b`),
|
|
504
587
|
p(EntityType.PHONE, String.raw `\b0[12]\d{2}[\s\-]?\d{3}[\s\-]?\d{4}\b`),
|
|
@@ -514,7 +597,7 @@ const BG = {
|
|
|
514
597
|
patterns: [
|
|
515
598
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{10}\b`, "bulgarian_egn"),
|
|
516
599
|
p(EntityType.IBAN, String.raw `\bBG\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}\b`, "iban"),
|
|
517
|
-
p(EntityType.VAT, String.raw `\bBG\d{9,10}\b`),
|
|
600
|
+
p(EntityType.VAT, String.raw `\bBG[\s.]?\d{9,10}\b`),
|
|
518
601
|
p(EntityType.PHONE, String.raw `\b0?[89][789][\s\-]?\d{3}[\s\-]?\d{3,4}\b`),
|
|
519
602
|
p(EntityType.PHONE, String.raw `\b0?[89][789]\d{7,8}\b`),
|
|
520
603
|
p(EntityType.PHONE, String.raw `\+359\s?[89][789][\s\-]?\d{3}[\s\-]?\d{3,4}`),
|
|
@@ -529,7 +612,7 @@ const CY = {
|
|
|
529
612
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{8}[A-Z]\b`),
|
|
530
613
|
p(EntityType.IBAN, String.raw `\bCY\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
531
614
|
p(EntityType.IBAN, String.raw `\bCY\d{26}\b`, "iban"),
|
|
532
|
-
p(EntityType.VAT, String.raw `\bCY\d{8}[A-Z]\b`),
|
|
615
|
+
p(EntityType.VAT, String.raw `\bCY[\s.]?\d{8}[A-Z]\b`),
|
|
533
616
|
p(EntityType.PHONE, String.raw `\b[29]\d{3}[\s\-]?\d{4}\b`),
|
|
534
617
|
p(EntityType.PHONE, String.raw `\b[29]\d[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
535
618
|
p(EntityType.PHONE, String.raw `\b[29]\d{7}\b`),
|
|
@@ -545,7 +628,7 @@ const CZ = {
|
|
|
545
628
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{6}/?\d{3,4}\b`, "czech_birth_number"),
|
|
546
629
|
p(EntityType.IBAN, String.raw `\bCZ\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
547
630
|
p(EntityType.IBAN, String.raw `\bCZ\d{22}\b`, "iban"),
|
|
548
|
-
p(EntityType.VAT, String.raw `\bCZ\d{8,10}\b`),
|
|
631
|
+
p(EntityType.VAT, String.raw `\bCZ[\s.]?\d{8,10}\b`),
|
|
549
632
|
p(EntityType.PHONE, String.raw `\b[67]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
550
633
|
p(EntityType.PHONE, String.raw `\b[67]\d{8}\b`),
|
|
551
634
|
p(EntityType.PHONE, String.raw `\+420\s?[67]\d{2}[\s\-]?\d{3}[\s\-]?\d{3}`),
|
|
@@ -559,7 +642,7 @@ const SK = {
|
|
|
559
642
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{6}/?\d{3,4}\b`, "czech_birth_number"),
|
|
560
643
|
p(EntityType.IBAN, String.raw `\bSK\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
561
644
|
p(EntityType.IBAN, String.raw `\bSK\d{22}\b`, "iban"),
|
|
562
|
-
p(EntityType.VAT, String.raw `\bSK\d{10}\b`),
|
|
645
|
+
p(EntityType.VAT, String.raw `\bSK[\s.]?\d{10}\b`),
|
|
563
646
|
p(EntityType.PHONE, String.raw `\b0?9\d{2}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
564
647
|
p(EntityType.PHONE, String.raw `\+421\s?9\d{2}[\s\-]?\d{3}[\s\-]?\d{3}`),
|
|
565
648
|
p(EntityType.POSTAL_CODE, String.raw `\b\d{3}\s?\d{2}\b`, null, "", ["PSČ", "poštové", "adresa", "ulica", "Postal:", "Address:"], true),
|
|
@@ -572,7 +655,7 @@ const EE = {
|
|
|
572
655
|
p(EntityType.NATIONAL_ID, String.raw `\b[1-6]\d{10}\b`, "estonian_id"),
|
|
573
656
|
p(EntityType.IBAN, String.raw `\bEE\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
574
657
|
p(EntityType.IBAN, String.raw `\bEE\d{18}\b`, "iban"),
|
|
575
|
-
p(EntityType.VAT, String.raw `\bEE\d{9}\b`),
|
|
658
|
+
p(EntityType.VAT, String.raw `\bEE[\s.]?\d{9}\b`),
|
|
576
659
|
p(EntityType.PHONE, String.raw `\b5\d{3}[\s\-]?\d{4}\b`),
|
|
577
660
|
p(EntityType.PHONE, String.raw `\b5\d{7}\b`),
|
|
578
661
|
p(EntityType.PHONE, String.raw `\+372\s?5\d{3}[\s\-]?\d{3,4}`),
|
|
@@ -586,7 +669,7 @@ const LT = {
|
|
|
586
669
|
p(EntityType.NATIONAL_ID, String.raw `\b[1-6]\d{10}\b`, "estonian_id"),
|
|
587
670
|
p(EntityType.IBAN, String.raw `\bLT\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
588
671
|
p(EntityType.IBAN, String.raw `\bLT\d{18}\b`, "iban"),
|
|
589
|
-
p(EntityType.VAT, String.raw `\bLT\d{9,12}\b`),
|
|
672
|
+
p(EntityType.VAT, String.raw `\bLT[\s.]?\d{9,12}\b`),
|
|
590
673
|
p(EntityType.PHONE, String.raw `\b6\d{2}[\s\-]?\d{2}[\s\-]?\d{3}\b`),
|
|
591
674
|
p(EntityType.PHONE, String.raw `\b6\d{7}\b`),
|
|
592
675
|
p(EntityType.PHONE, String.raw `\b8[\s\-]?6\d{2}[\s\-]?\d{2}[\s\-]?\d{3}\b`),
|
|
@@ -602,7 +685,7 @@ const LV = {
|
|
|
602
685
|
p(EntityType.NATIONAL_ID, String.raw `\b(?:0[1-9]|[12]\d|3[01])(?:0[1-9]|1[0-2])\d{7}\b`, null, "", ["personas kods", "PK", "identifikācijas"], true),
|
|
603
686
|
p(EntityType.IBAN, String.raw `\bLV\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d\b`, "iban"),
|
|
604
687
|
p(EntityType.IBAN, String.raw `\bLV\d{2}[A-Z]{4}\d{13}\b`, "iban"),
|
|
605
|
-
p(EntityType.VAT, String.raw `\bLV\d{11}\b`),
|
|
688
|
+
p(EntityType.VAT, String.raw `\bLV[\s.]?\d{11}\b`),
|
|
606
689
|
p(EntityType.PHONE, String.raw `\b[2]\d{3}[\s\-]?\d{4}\b`),
|
|
607
690
|
p(EntityType.PHONE, String.raw `\b[2]\d{7}\b`),
|
|
608
691
|
p(EntityType.PHONE, String.raw `\+371\s?[2]\d{3}[\s\-]?\d{3,4}`),
|
|
@@ -617,7 +700,7 @@ const HR = {
|
|
|
617
700
|
p(EntityType.IBAN, String.raw `\bHR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}\b`, "iban"),
|
|
618
701
|
p(EntityType.IBAN, String.raw `\bHR\d{2}\s\d{4}\s\d{4}\s\d{4}\s\d{5}\b`, "iban"),
|
|
619
702
|
p(EntityType.IBAN, String.raw `\bHR\d{19}\b`, "iban"),
|
|
620
|
-
p(EntityType.VAT, String.raw `\bHR\d{11}\b`),
|
|
703
|
+
p(EntityType.VAT, String.raw `\bHR[\s.]?\d{11}\b`),
|
|
621
704
|
p(EntityType.PHONE, String.raw `\b0?9[12579][\s\-]?\d{3}[\s\-]?\d{3,4}\b`),
|
|
622
705
|
p(EntityType.PHONE, String.raw `\b0?9[12579]\d{7,8}\b`),
|
|
623
706
|
p(EntityType.PHONE, String.raw `\+385\s?9[12579][\s\-]?\d{3}[\s\-]?\d{3,4}`),
|
|
@@ -631,7 +714,7 @@ const HU = {
|
|
|
631
714
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{9}\b`, "hungarian_taj"),
|
|
632
715
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{3}\s\d{3}\s\d{3}\b`, "hungarian_taj"),
|
|
633
716
|
p(EntityType.TAX_ID, String.raw `\b8\d{9}\b`, null, "", ["adóazonosító", "adószám", "adóazonosító jel"], true),
|
|
634
|
-
p(EntityType.VAT, String.raw `\bHU\d{8,11}\b`, null, "", ["adószám", "ÁFA"]),
|
|
717
|
+
p(EntityType.VAT, String.raw `\bHU[\s.]?\d{8,11}\b`, null, "", ["adószám", "ÁFA"]),
|
|
635
718
|
p(EntityType.IBAN, String.raw `\bHU\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b`, "iban"),
|
|
636
719
|
p(EntityType.IBAN, String.raw `\bHU\d{26}\b`, "iban"),
|
|
637
720
|
p(EntityType.PHONE, String.raw `\b06\s?\d{1,2}[\s\-]?\d{3}[\s\-]?\d{3,4}\b`),
|
|
@@ -646,7 +729,7 @@ const RO = {
|
|
|
646
729
|
patterns: [
|
|
647
730
|
p(EntityType.NATIONAL_ID, String.raw `\b[1-8]\d{12}\b`, "romanian_cnp"),
|
|
648
731
|
p(EntityType.IBAN, String.raw `\bRO\d{2}[A-Z]{4}\d{16}\b`, "iban"),
|
|
649
|
-
p(EntityType.VAT, String.raw `\bRO\d{2,10}\b`),
|
|
732
|
+
p(EntityType.VAT, String.raw `\bRO[\s.]?\d{2,10}\b`),
|
|
650
733
|
p(EntityType.PHONE, String.raw `\b0?7[2-9]\d{1}[\s\-]?\d{3}[\s\-]?\d{3,4}\b`),
|
|
651
734
|
p(EntityType.PHONE, String.raw `\b0?7[2-9]\d{7,8}\b`),
|
|
652
735
|
p(EntityType.PHONE, String.raw `\+40\s?7[2-9]\d{1}[\s\-]?\d{3}[\s\-]?\d{3,4}`),
|
|
@@ -661,7 +744,7 @@ const EL = {
|
|
|
661
744
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{11}\b`, "greek_amka"),
|
|
662
745
|
p(EntityType.IBAN, String.raw `\bGR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}\b`, "iban"),
|
|
663
746
|
p(EntityType.IBAN, String.raw `\bGR\d{25}\b`, "iban"),
|
|
664
|
-
p(EntityType.VAT, String.raw `\bEL\d{9}\b`),
|
|
747
|
+
p(EntityType.VAT, String.raw `\bEL[\s.]?\d{9}\b`),
|
|
665
748
|
p(EntityType.PHONE, String.raw `\b69\d[\s\-]?\d{3,4}[\s\-]?\d{4}\b`),
|
|
666
749
|
p(EntityType.PHONE, String.raw `\b69\d{8}\b`),
|
|
667
750
|
p(EntityType.PHONE, String.raw `\b2\d{1,3}[\s\-]?\d{3,4}[\s\-]?\d{3,4}\b`),
|
|
@@ -676,7 +759,7 @@ const SI = {
|
|
|
676
759
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{13}\b`, "slovenian_emso"),
|
|
677
760
|
p(EntityType.IBAN, String.raw `\bSI\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}\b`, "iban"),
|
|
678
761
|
p(EntityType.IBAN, String.raw `\bSI\d{17}\b`, "iban"),
|
|
679
|
-
p(EntityType.VAT, String.raw `\bSI\d{8}\b`),
|
|
762
|
+
p(EntityType.VAT, String.raw `\bSI[\s.]?\d{8}\b`),
|
|
680
763
|
p(EntityType.PHONE, String.raw `\b0?[34567]\d{1}[\s\-]?\d{3}[\s\-]?\d{3}\b`),
|
|
681
764
|
p(EntityType.PHONE, String.raw `\b0?[34567]\d{7}\b`),
|
|
682
765
|
p(EntityType.PHONE, String.raw `\+386\s?[34567]\d{1}[\s\-]?\d{3}[\s\-]?\d{3}`),
|
|
@@ -691,7 +774,7 @@ const MT = {
|
|
|
691
774
|
p(EntityType.NATIONAL_ID, String.raw `\b\d{5,7}[MGAPLHBZ]\b`),
|
|
692
775
|
p(EntityType.IBAN, String.raw `\bMT\d{2}\s?[A-Z]{4}\s?\d{4}\s?\d{4}\s?[A-Z0-9]{4}\s?[A-Z0-9]{4}\s?[A-Z0-9]{4}\s?[A-Z0-9]{3}\b`, "iban"),
|
|
693
776
|
p(EntityType.IBAN, String.raw `\bMT\d{2}[A-Z]{4}\d{5}[A-Z0-9]{18}\b`, "iban"),
|
|
694
|
-
p(EntityType.VAT, String.raw `\bMT\d{8}\b`),
|
|
777
|
+
p(EntityType.VAT, String.raw `\bMT[\s.]?\d{8}\b`),
|
|
695
778
|
p(EntityType.PHONE, String.raw `\b[79]\d{3}[\s\-]?\d{4}\b`),
|
|
696
779
|
p(EntityType.PHONE, String.raw `\b[79]\d{7}\b`),
|
|
697
780
|
p(EntityType.PHONE, String.raw `\+356\s?[79]\d{3}[\s\-]?\d{3,4}`),
|
package/dist/esm/rules/cues.d.ts
CHANGED
|
@@ -64,8 +64,20 @@ import { EntityType } from "../types.js";
|
|
|
64
64
|
* How far back a cue may sit. Short on purpose: a cue is only evidence about
|
|
65
65
|
* the value it introduces, which is the lesson of the postal-code year defect,
|
|
66
66
|
* where a cue 150 characters away licensed every number in the window.
|
|
67
|
+
*
|
|
68
|
+
* This bounds how long a *label* may be, not how far it may sit from the
|
|
69
|
+
* value: every pattern is anchored with `$`, so the label still has to reach
|
|
70
|
+
* the span through a run-on or one qualifier word.
|
|
71
|
+
*
|
|
72
|
+
* 32 was too short for German tax labels, the longest the engine carries.
|
|
73
|
+
* "Steuerliche Identifikationsnummer " is 34 characters and
|
|
74
|
+
* "Steueridentifikationsnummer lautet: " is 36, so the label's own start sat
|
|
75
|
+
* outside the window and `(?<![A-Za-z0-9_])` had nothing to anchor against,
|
|
76
|
+
* leaving a critical-tier identifier in the clear (rules-engine#26). 44
|
|
77
|
+
* admits the longest with a qualifier: "Steuerliche Identifikationsnummer
|
|
78
|
+
* lautet: " is 42.
|
|
67
79
|
*/
|
|
68
|
-
export declare const CUE_WINDOW =
|
|
80
|
+
export declare const CUE_WINDOW = 44;
|
|
69
81
|
/**
|
|
70
82
|
* (entity type, label pattern). Ordered: the first match wins, so the narrower
|
|
71
83
|
* label comes first where two could read the same text.
|
package/dist/esm/rules/cues.js
CHANGED
|
@@ -64,8 +64,20 @@ import { EntityType } from "../types.js";
|
|
|
64
64
|
* How far back a cue may sit. Short on purpose: a cue is only evidence about
|
|
65
65
|
* the value it introduces, which is the lesson of the postal-code year defect,
|
|
66
66
|
* where a cue 150 characters away licensed every number in the window.
|
|
67
|
+
*
|
|
68
|
+
* This bounds how long a *label* may be, not how far it may sit from the
|
|
69
|
+
* value: every pattern is anchored with `$`, so the label still has to reach
|
|
70
|
+
* the span through a run-on or one qualifier word.
|
|
71
|
+
*
|
|
72
|
+
* 32 was too short for German tax labels, the longest the engine carries.
|
|
73
|
+
* "Steuerliche Identifikationsnummer " is 34 characters and
|
|
74
|
+
* "Steueridentifikationsnummer lautet: " is 36, so the label's own start sat
|
|
75
|
+
* outside the window and `(?<![A-Za-z0-9_])` had nothing to anchor against,
|
|
76
|
+
* leaving a critical-tier identifier in the clear (rules-engine#26). 44
|
|
77
|
+
* admits the longest with a qualifier: "Steuerliche Identifikationsnummer
|
|
78
|
+
* lautet: " is 42.
|
|
67
79
|
*/
|
|
68
|
-
export const CUE_WINDOW =
|
|
80
|
+
export const CUE_WINDOW = 44;
|
|
69
81
|
/**
|
|
70
82
|
* (entity type, label pattern). Ordered: the first match wins, so the narrower
|
|
71
83
|
* label comes first where two could read the same text.
|
|
@@ -88,8 +100,15 @@ export const CUES = [
|
|
|
88
100
|
/(?<![A-Za-z0-9_])(?:ssn|social\s*security|sozialversicherungsnummer|svnr|sofi)(?:(?:[A-Za-z0-9_]|[^\x00-\x7F])*|\s+[^\s:.\-\d,;()\/]{2,20})\s*\)?\s*[:.\-]*\s*$/i],
|
|
89
101
|
// Tax number. Greece's ΑΦΜ is issued by the tax authority; the identity-card
|
|
90
102
|
// number is the ΑΔΤ, above.
|
|
103
|
+
//
|
|
104
|
+
// The German long forms are spelled out rather than left to the run-on after
|
|
105
|
+
// `steuer-?id`. A cue may use its run-on *or* one qualifier word, never both,
|
|
106
|
+
// and "Steuer-IdNr lautet:" needs both: the run-on for "Nr" and the qualifier
|
|
107
|
+
// for "lautet". Naming the whole label leaves the qualifier free.
|
|
108
|
+
// "Steuerliche Identifikationsnummer" matched nothing at all — it is two
|
|
109
|
+
// words, and `steuer-?id` cannot reach across "liche " (rules-engine#26).
|
|
91
110
|
[EntityType.TAX_ID,
|
|
92
|
-
/(?<![A-Za-z0-9_])(?:αφμ|α\.φ\.μ\.|steuer-?id|steuernummer|st\.?-?nr|stnr|tin|finanzamt\s+ist|tax\s*(?:id|no|number)|daňové\s*číslo|numer\s*podatkowy)(?:(?:[A-Za-z0-9_]|[^\x00-\x7F])*|\s+[^\s:.\-\d,;()\/]{2,20})\s*\)?\s*[:.\-]*\s*$/i],
|
|
111
|
+
/(?<![A-Za-z0-9_])(?:αφμ|α\.φ\.μ\.|steuerliche\s*identifikations-?nummer|steuer-?identifikations-?nummer|steuer-?id-?nr\.?|steuer-?id|steuernummer|st\.?-?nr|stnr|tin|finanzamt\s+ist|tax\s*(?:id|no|number)|daňové\s*číslo|numer\s*podatkowy)(?:(?:[A-Za-z0-9_]|[^\x00-\x7F])*|\s+[^\s:.\-\d,;()\/]{2,20})\s*\)?\s*[:.\-]*\s*$/i],
|
|
93
112
|
// Health insurance: the insured person.
|
|
94
113
|
[EntityType.HEALTH_INSURANCE,
|
|
95
114
|
/(?<![A-Za-z0-9_])(?:versichertennummer|krankenversicherung|kvnr|kv-?nr|mutualité|ziekenfonds|aansluitingsnummer|medical\s*card(?:\s*(?:no|number))?)(?:(?:[A-Za-z0-9_]|[^\x00-\x7F])*|\s+[^\s:.\-\d,;()\/]{2,20})\s*\)?\s*[:.\-]*\s*$/i],
|