This commit is contained in:
@@ -48,6 +48,51 @@ const GERMAN_NUMBER_WORDS = new Map([
|
||||
['zweitausend', '2000']
|
||||
]);
|
||||
|
||||
const GERMAN_NUMBER_PARTS = new Map([
|
||||
['null', 0],
|
||||
['ein', 1],
|
||||
['eins', 1],
|
||||
['eine', 1],
|
||||
['einen', 1],
|
||||
['einem', 1],
|
||||
['einer', 1],
|
||||
['zwei', 2],
|
||||
['drei', 3],
|
||||
['vier', 4],
|
||||
['fuenf', 5],
|
||||
['funf', 5],
|
||||
['fünf', 5],
|
||||
['sechs', 6],
|
||||
['sieben', 7],
|
||||
['acht', 8],
|
||||
['neun', 9],
|
||||
['zehn', 10],
|
||||
['elf', 11],
|
||||
['zwoelf', 12],
|
||||
['zwolf', 12],
|
||||
['zwölf', 12],
|
||||
['dreizehn', 13],
|
||||
['vierzehn', 14],
|
||||
['fuenfzehn', 15],
|
||||
['funfzehn', 15],
|
||||
['fünfzehn', 15],
|
||||
['sechzehn', 16],
|
||||
['siebzehn', 17],
|
||||
['achtzehn', 18],
|
||||
['neunzehn', 19],
|
||||
['zwanzig', 20],
|
||||
['dreissig', 30],
|
||||
['dreißig', 30],
|
||||
['vierzig', 40],
|
||||
['fuenfzig', 50],
|
||||
['funfzig', 50],
|
||||
['fünfzig', 50],
|
||||
['sechzig', 60],
|
||||
['siebzig', 70],
|
||||
['achtzig', 80],
|
||||
['neunzig', 90]
|
||||
]);
|
||||
|
||||
const GERMAN_ONES = [
|
||||
['', ''],
|
||||
['ein', 'eins'],
|
||||
@@ -88,6 +133,60 @@ function stripGermanNumberSeparators(value) {
|
||||
.replace(/[\s.-]+/g, '');
|
||||
}
|
||||
|
||||
function parseGermanUnderHundred(compact) {
|
||||
if (!compact) return null;
|
||||
if (GERMAN_NUMBER_PARTS.has(compact)) {
|
||||
return GERMAN_NUMBER_PARTS.get(compact);
|
||||
}
|
||||
|
||||
const undIndex = compact.indexOf('und');
|
||||
if (undIndex > 0) {
|
||||
const onesPart = compact.slice(0, undIndex);
|
||||
const tensPart = compact.slice(undIndex + 3);
|
||||
const ones = GERMAN_NUMBER_PARTS.get(onesPart);
|
||||
const tens = GERMAN_NUMBER_PARTS.get(tensPart);
|
||||
if (ones >= 1 && ones <= 9 && tens >= 20 && tens % 10 === 0) {
|
||||
return tens + ones;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function parseGermanNumberWord(compact) {
|
||||
if (!compact) return null;
|
||||
if (/^\d+$/.test(compact)) {
|
||||
return Number(compact);
|
||||
}
|
||||
if (GERMAN_NUMBER_PARTS.has(compact)) {
|
||||
return GERMAN_NUMBER_PARTS.get(compact);
|
||||
}
|
||||
|
||||
const tausendIndex = compact.indexOf('tausend');
|
||||
if (tausendIndex !== -1) {
|
||||
const thousandsPart = compact.slice(0, tausendIndex);
|
||||
const remainderPart = compact.slice(tausendIndex + 'tausend'.length);
|
||||
const thousands = thousandsPart ? parseGermanNumberWord(thousandsPart) : 1;
|
||||
const remainder = remainderPart ? parseGermanNumberWord(remainderPart) : 0;
|
||||
if (thousands !== null && remainder !== null) {
|
||||
return thousands * 1000 + remainder;
|
||||
}
|
||||
}
|
||||
|
||||
const hundertIndex = compact.indexOf('hundert');
|
||||
if (hundertIndex !== -1) {
|
||||
const hundredsPart = compact.slice(0, hundertIndex);
|
||||
const remainderPart = compact.slice(hundertIndex + 'hundert'.length);
|
||||
const hundreds = hundredsPart ? parseGermanNumberWord(hundredsPart) : 1;
|
||||
const remainder = remainderPart ? parseGermanUnderHundred(remainderPart) : 0;
|
||||
if (hundreds !== null && remainder !== null) {
|
||||
return hundreds * 100 + remainder;
|
||||
}
|
||||
}
|
||||
|
||||
return parseGermanUnderHundred(compact);
|
||||
}
|
||||
|
||||
export function canonicalizeNumberAnswer(value) {
|
||||
const raw = String(value || '').trim().toLowerCase();
|
||||
if (!raw) return '';
|
||||
@@ -97,6 +196,11 @@ export function canonicalizeNumberAnswer(value) {
|
||||
return String(Number(compact));
|
||||
}
|
||||
|
||||
const parsed = parseGermanNumberWord(compact);
|
||||
if (parsed !== null) {
|
||||
return String(parsed);
|
||||
}
|
||||
|
||||
return GERMAN_NUMBER_WORDS.get(compact) || '';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user