@openhealth/oht-custom-parser-lib 0.2.74 → 0.2.75
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/dist/index.d.ts +2 -0
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/service/ohtAgnosticMeasurementsExtractor.service.d.ts +59 -0
- package/dist/service/ohtAgnosticMeasurementsExtractor.service.js +603 -0
- package/dist/service/ohtAgnosticMeasurementsExtractor.service.js.map +1 -0
- package/dist/service/ohtMeasurementsExtractor.service.d.ts +0 -27
- package/dist/service/ohtMeasurementsExtractor.service.js +31 -68
- package/dist/service/ohtMeasurementsExtractor.service.js.map +1 -1
- package/dist/types/custom-parser.types.d.ts +9 -1
- package/dist/types/oht.types.d.ts +4 -3
- package/dist/util-ts/extractionUtils.d.ts +10 -0
- package/dist/util-ts/extractionUtils.js +398 -0
- package/dist/util-ts/extractionUtils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseRange = parseRange;
|
|
7
|
+
const moment_1 = __importDefault(require("moment"));
|
|
8
|
+
/**
|
|
9
|
+
* Default range parsing function that extracts range information from exam data
|
|
10
|
+
* @param exam - The OHT exam object containing range information
|
|
11
|
+
* @param labToOhtMapper - The lab to OHT mapper configuration
|
|
12
|
+
* @returns Range extraction response with parsed range bounds
|
|
13
|
+
*/
|
|
14
|
+
function parseRange(exam, labToOhtMapper, patientInfo) {
|
|
15
|
+
// Define document date with priority:
|
|
16
|
+
// 1. collectionDate
|
|
17
|
+
// 2. effectiveDate
|
|
18
|
+
// 3. examCollectionDate
|
|
19
|
+
// 4. examEffectiveDate
|
|
20
|
+
// 5. documentDate
|
|
21
|
+
const documentDate = exam.collectionDate ||
|
|
22
|
+
exam.effectiveDate ||
|
|
23
|
+
exam.examCollectionDate ||
|
|
24
|
+
exam.examEffectiveDate ||
|
|
25
|
+
exam.documentDate;
|
|
26
|
+
const age = patientInfo.birthdate ? (0, moment_1.default)(documentDate).diff((0, moment_1.default)(patientInfo.birthdate), 'years', false) : null;
|
|
27
|
+
const sex = patientInfo.sex;
|
|
28
|
+
// If patient age is not available, return early
|
|
29
|
+
if (age === null) {
|
|
30
|
+
return { from: null, to: null, isRangeParsedCorrectly: false };
|
|
31
|
+
}
|
|
32
|
+
// if noSourceRanges is true, return early and set isRangeParsedCorrectly to true
|
|
33
|
+
if (exam.range.some(range => range.noSourceRanges)) {
|
|
34
|
+
return { from: null, to: null, isRangeParsedCorrectly: true };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Checks if a range age string matches the patient's age
|
|
38
|
+
* Supports formats: ">70", "30-50", "19+", "<10", "adult"
|
|
39
|
+
*/
|
|
40
|
+
const doesAgeMatch = (rangeAge, patientAge) => {
|
|
41
|
+
if (!rangeAge || rangeAge.trim() === '') {
|
|
42
|
+
return false; // No age info - will be handled separately
|
|
43
|
+
}
|
|
44
|
+
const ageStr = rangeAge.trim().toLowerCase();
|
|
45
|
+
// "adult" matches all adults (18+)
|
|
46
|
+
if (ageStr === 'adult') {
|
|
47
|
+
return patientAge >= 18;
|
|
48
|
+
}
|
|
49
|
+
// Range format: "30-50"
|
|
50
|
+
const rangeMatch = ageStr.match(/^(\d+)-(\d+)$/);
|
|
51
|
+
if (rangeMatch) {
|
|
52
|
+
const lowerAge = parseInt(rangeMatch[1]);
|
|
53
|
+
const upperAge = parseInt(rangeMatch[2]);
|
|
54
|
+
return patientAge >= lowerAge && patientAge <= upperAge;
|
|
55
|
+
}
|
|
56
|
+
// Greater than format: ">70" or "70+"
|
|
57
|
+
const greaterThanMatch = ageStr.match(/^>?(\d+)\+?$/);
|
|
58
|
+
if (greaterThanMatch) {
|
|
59
|
+
const minAge = parseInt(greaterThanMatch[1]);
|
|
60
|
+
return patientAge >= minAge;
|
|
61
|
+
}
|
|
62
|
+
// Less than format: "<10"
|
|
63
|
+
const lessThanMatch = ageStr.match(/^<(\d+)$/);
|
|
64
|
+
if (lessThanMatch) {
|
|
65
|
+
const maxAge = parseInt(lessThanMatch[1]);
|
|
66
|
+
return patientAge < maxAge;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Checks if a range sex matches the patient's sex
|
|
72
|
+
* "ADULT" matches any patient sex (MALE or FEMALE)
|
|
73
|
+
*/
|
|
74
|
+
const doesSexMatch = (rangeSex, patientSex) => {
|
|
75
|
+
if (!rangeSex || rangeSex.trim() === '') {
|
|
76
|
+
return false; // No sex info - will be handled separately
|
|
77
|
+
}
|
|
78
|
+
const rangeSexUpper = rangeSex.trim().toUpperCase();
|
|
79
|
+
const patientSexUpper = patientSex.trim().toUpperCase();
|
|
80
|
+
// "ADULT" matches any patient sex (MALE or FEMALE)
|
|
81
|
+
if (rangeSexUpper === 'ADULT') {
|
|
82
|
+
return patientSexUpper === 'MALE' || patientSexUpper === 'FEMALE';
|
|
83
|
+
}
|
|
84
|
+
return rangeSexUpper === patientSexUpper;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Checks if range text mentions opposite sex (fallback when range.sex is not available)
|
|
88
|
+
* Returns false if both sexes are mentioned (range applies to everyone)
|
|
89
|
+
*/
|
|
90
|
+
const mentionsOppositeSex = (rangeText, patientSex) => {
|
|
91
|
+
const lower = rangeText.toLowerCase();
|
|
92
|
+
// Check if both sexes are mentioned - if so, range applies to everyone
|
|
93
|
+
const hasMasculine = lower.includes("homens") || lower.includes("masculino");
|
|
94
|
+
const hasFeminine = lower.includes("mulheres") || lower.includes("feminino");
|
|
95
|
+
if (hasMasculine && hasFeminine) {
|
|
96
|
+
return false; // Both sexes mentioned, so it's not opposite sex only
|
|
97
|
+
}
|
|
98
|
+
if (patientSex === "MALE") {
|
|
99
|
+
return hasFeminine;
|
|
100
|
+
}
|
|
101
|
+
else if (patientSex === "FEMALE") {
|
|
102
|
+
return hasMasculine;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Calculates precision score (0-100) for a range
|
|
108
|
+
* Higher score = more precise/appropriate range
|
|
109
|
+
*/
|
|
110
|
+
const calculatePrecisionScore = (range, patientAge, patientSex) => {
|
|
111
|
+
let score = 50; // Base score for ranges without info
|
|
112
|
+
const hasAgeInfo = !!range.age && range.age.trim() !== '';
|
|
113
|
+
const hasSexInfo = !!range.sex && range.sex.trim() !== '';
|
|
114
|
+
// Penalize ranges without age/sex info
|
|
115
|
+
if (!hasAgeInfo && !hasSexInfo) {
|
|
116
|
+
score = 30; // Lower score for generic ranges
|
|
117
|
+
}
|
|
118
|
+
// Age matching bonuses
|
|
119
|
+
if (hasAgeInfo) {
|
|
120
|
+
if (doesAgeMatch(range.age, patientAge)) {
|
|
121
|
+
score += 30; // Exact age match
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
score += 10; // Has age info but doesn't match (still better than no info)
|
|
125
|
+
}
|
|
126
|
+
// Additional specificity bonus for age ranges
|
|
127
|
+
if (range.age) {
|
|
128
|
+
const ageRangeMatch = range.age.match(/^(\d+)-(\d+)$/);
|
|
129
|
+
if (ageRangeMatch) {
|
|
130
|
+
const lowerAge = parseInt(ageRangeMatch[1]);
|
|
131
|
+
const upperAge = parseInt(ageRangeMatch[2]);
|
|
132
|
+
const rangeSize = upperAge - lowerAge;
|
|
133
|
+
// Smaller range = higher specificity (max 15 points)
|
|
134
|
+
const specificityBonus = Math.max(0, 15 - Math.floor(rangeSize / 5));
|
|
135
|
+
score += specificityBonus;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Sex matching bonuses
|
|
140
|
+
if (hasSexInfo) {
|
|
141
|
+
if (doesSexMatch(range.sex, patientSex)) {
|
|
142
|
+
score += 20; // Exact sex match
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
score += 5; // Has sex info but doesn't match (still better than no info)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Cap at 100
|
|
149
|
+
return Math.min(100, score);
|
|
150
|
+
};
|
|
151
|
+
// Helper function to try parsing range from text
|
|
152
|
+
const tryParseFromText = (text) => {
|
|
153
|
+
// Helper function to attempt extraction from a given text string
|
|
154
|
+
const attemptExtraction = (textToSearch) => {
|
|
155
|
+
// Try standard range pattern (e.g., "70-100", "70 a 100", "70.5-100.2", "70,5 a 100,2", "de 2,0 até 4,1")
|
|
156
|
+
// Exclude ranges followed by "ano" or "anos" (e.g., "70 a 100 anos")
|
|
157
|
+
const rangeRegex = /(?:de\s+)?(\d+(?:[.,]\d+)?)\s*(?:[-]|à|a|A|À|até)\s*(\d+(?:[.,]\d+)?)(?!\s*(?:ano|anos|Ano|Anos)\b)/u;
|
|
158
|
+
const rangeMatch = rangeRegex.exec(textToSearch);
|
|
159
|
+
if (rangeMatch) {
|
|
160
|
+
try {
|
|
161
|
+
const value1 = parsePtNumber(rangeMatch[1]);
|
|
162
|
+
const value2 = parsePtNumber(rangeMatch[2]);
|
|
163
|
+
if (!isNaN(value1) && !isNaN(value2) && value2 >= value1) {
|
|
164
|
+
return { from: value1, to: value2, isRangeParsedCorrectly: true };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// Continue to next pattern if parsing fails
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Try "até X" pattern (works even when "até" is not at the start of the string)
|
|
172
|
+
// This handles cases like "Valor de Referência: até 40,0 µg/dL"
|
|
173
|
+
const atePattern = /at[eé]\s+([\d\.,]+)/i;
|
|
174
|
+
const ateMatch = atePattern.exec(textToSearch);
|
|
175
|
+
if (ateMatch) {
|
|
176
|
+
try {
|
|
177
|
+
const value = parsePtNumber(ateMatch[1]);
|
|
178
|
+
if (!isNaN(value)) {
|
|
179
|
+
return { from: null, to: value, isRangeParsedCorrectly: true };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
// Continue to next pattern if parsing fails
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Try "less than" patterns
|
|
187
|
+
const lessThanPatterns = getLessThanPatterns();
|
|
188
|
+
for (const pattern of lessThanPatterns) {
|
|
189
|
+
try {
|
|
190
|
+
const match = pattern.exec(textToSearch.toLowerCase());
|
|
191
|
+
if (match) {
|
|
192
|
+
const value = parsePtNumber(match[1]);
|
|
193
|
+
if (!isNaN(value)) {
|
|
194
|
+
return { from: null, to: value, isRangeParsedCorrectly: true };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// Continue to next pattern if parsing fails
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Try "greater than" patterns
|
|
203
|
+
const greaterThanPatterns = getGreaterThanPatterns();
|
|
204
|
+
for (const pattern of greaterThanPatterns) {
|
|
205
|
+
try {
|
|
206
|
+
const match = pattern.exec(textToSearch.toLowerCase());
|
|
207
|
+
if (match) {
|
|
208
|
+
const value = parsePtNumber(match[1]);
|
|
209
|
+
if (!isNaN(value)) {
|
|
210
|
+
return { from: value, to: null, isRangeParsedCorrectly: true };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
// Continue to next pattern if parsing fails
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Try to extract ignoring unit (e.g 41,68 U/mL a 95,06 U/mL)
|
|
219
|
+
const ignoringUnitRegex = /(\d+(?:[.,]\d+)?)\s*[^0-9]*?\s*[AaÀà-]\s*(\d+(?:[.,]\d+)?)/;
|
|
220
|
+
const ignoringUnitMatch = ignoringUnitRegex.exec(textToSearch.toLowerCase());
|
|
221
|
+
if (ignoringUnitMatch) {
|
|
222
|
+
try {
|
|
223
|
+
const value1 = parsePtNumber(ignoringUnitMatch[1] || '');
|
|
224
|
+
const value2 = parsePtNumber(ignoringUnitMatch[2] || '');
|
|
225
|
+
if (!isNaN(value1) && !isNaN(value2) && value2 >= value1) {
|
|
226
|
+
return { from: value1, to: value2, isRangeParsedCorrectly: true };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
// Continue to next attempt if parsing fails
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
};
|
|
235
|
+
// If text contains ":", try extraction from both parts
|
|
236
|
+
// First try part after ":", then try part before ":"
|
|
237
|
+
if (text.includes(':')) {
|
|
238
|
+
const parts = text.split(':');
|
|
239
|
+
const beforeColon = parts[0].trim();
|
|
240
|
+
const afterColon = parts.slice(1).join(':').trim();
|
|
241
|
+
// Try extraction from part after ":" first
|
|
242
|
+
if (afterColon) {
|
|
243
|
+
const result = attemptExtraction(afterColon);
|
|
244
|
+
if (result && result.isRangeParsedCorrectly) {
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// If no result from after ":", try part before ":"
|
|
249
|
+
if (beforeColon) {
|
|
250
|
+
const result = attemptExtraction(beforeColon);
|
|
251
|
+
if (result && result.isRangeParsedCorrectly) {
|
|
252
|
+
return result;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// If no ":" or extraction from both parts failed, try full text
|
|
257
|
+
const result = attemptExtraction(text);
|
|
258
|
+
if (result) {
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
return { from: null, to: null, isRangeParsedCorrectly: false };
|
|
262
|
+
};
|
|
263
|
+
// Filter 1: Exclude ranges with opposite sex
|
|
264
|
+
// Use range.sex when available, otherwise check text
|
|
265
|
+
const sexFiltered = exam.range.filter(range => {
|
|
266
|
+
// If range has explicit sex info, use it
|
|
267
|
+
if (range.sex && range.sex.trim() !== '') {
|
|
268
|
+
return doesSexMatch(range.sex, sex);
|
|
269
|
+
}
|
|
270
|
+
// If no explicit sex info, check if text mentions opposite sex
|
|
271
|
+
// Only exclude if explicitly mentions opposite sex
|
|
272
|
+
if (sex && (sex === "MALE" || sex === "FEMALE")) {
|
|
273
|
+
return !mentionsOppositeSex(range.text, sex);
|
|
274
|
+
}
|
|
275
|
+
// If patient sex is unknown, keep all ranges
|
|
276
|
+
return true;
|
|
277
|
+
});
|
|
278
|
+
// Filter 2: Exclude ranges with age that doesn't match patient
|
|
279
|
+
// Prioritize ranges with age info that matches
|
|
280
|
+
const ageFiltered = sexFiltered.filter(range => {
|
|
281
|
+
// If range has explicit age info, check if it matches
|
|
282
|
+
if (range.age && range.age.trim() !== '') {
|
|
283
|
+
return doesAgeMatch(range.age, age);
|
|
284
|
+
}
|
|
285
|
+
// If no age info, keep it (will be scored lower)
|
|
286
|
+
return true;
|
|
287
|
+
});
|
|
288
|
+
// If we have ranges with age info that matches, use only those
|
|
289
|
+
// Otherwise, use all remaining ranges (including those without age info)
|
|
290
|
+
const rangesWithAgeInfo = ageFiltered.filter(r => r.age && r.age.trim() !== '');
|
|
291
|
+
let rangesToProcess = rangesWithAgeInfo.length > 0 ? rangesWithAgeInfo : ageFiltered;
|
|
292
|
+
// Sort ranges by precision score (highest first)
|
|
293
|
+
rangesToProcess = rangesToProcess.sort((a, b) => {
|
|
294
|
+
const scoreA = calculatePrecisionScore(a, age, sex);
|
|
295
|
+
const scoreB = calculatePrecisionScore(b, age, sex);
|
|
296
|
+
return scoreB - scoreA; // Higher score first
|
|
297
|
+
});
|
|
298
|
+
// Try to extract from filtered ranges (check all ranges in order)
|
|
299
|
+
if (rangesToProcess.length > 0) {
|
|
300
|
+
for (const range of rangesToProcess) {
|
|
301
|
+
// Special case: if from, to, and text are all "0", return directly
|
|
302
|
+
const fromTrimmed = (range.from != null && typeof range.from === 'string' ? range.from.trim() : (range.from != null ? String(range.from) : ''));
|
|
303
|
+
const toTrimmed = (range.to != null && typeof range.to === 'string' ? range.to.trim() : (range.to != null ? String(range.to) : ''));
|
|
304
|
+
const textTrimmed = (range.text != null && typeof range.text === 'string' ? range.text.trim() : (range.text != null ? String(range.text) : ''));
|
|
305
|
+
if (fromTrimmed === '0' && toTrimmed === '0' && textTrimmed === '0') {
|
|
306
|
+
return { from: 0, to: 0, isRangeParsedCorrectly: true };
|
|
307
|
+
}
|
|
308
|
+
const result = tryParseFromText(range.text);
|
|
309
|
+
if (result.isRangeParsedCorrectly)
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// If no range is parsed correctly, return null values
|
|
314
|
+
return { from: null, to: null, isRangeParsedCorrectly: false };
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Parses numbers with Portuguese-Brazilian thousand/decimal separators
|
|
318
|
+
* Examples handled:
|
|
319
|
+
* - "1.000" -> 1000
|
|
320
|
+
* - "1.234,56" -> 1234.56
|
|
321
|
+
* - "41,68" -> 41.68
|
|
322
|
+
* - "0.016" -> 0.016 (decimal format, not thousand separator)
|
|
323
|
+
* - "0.078" -> 0.078 (decimal format, not thousand separator)
|
|
324
|
+
* - falls back to replacing comma with dot otherwise
|
|
325
|
+
* @param raw - The raw string to parse
|
|
326
|
+
* @returns The parsed number or NaN if parsing fails
|
|
327
|
+
*/
|
|
328
|
+
function parsePtNumber(raw) {
|
|
329
|
+
if (raw == null)
|
|
330
|
+
return NaN;
|
|
331
|
+
const s = String(raw).trim();
|
|
332
|
+
if (s === '')
|
|
333
|
+
return NaN;
|
|
334
|
+
// Special case: values starting with "0." followed by 3+ digits are decimals (English format)
|
|
335
|
+
// This prevents "0.016" from being treated as thousand separator format
|
|
336
|
+
const decimalZeroPattern = /^0\.\d{3,}$/;
|
|
337
|
+
if (decimalZeroPattern.test(s)) {
|
|
338
|
+
return parseFloat(s);
|
|
339
|
+
}
|
|
340
|
+
const ptPattern = /^\d{1,3}(?:\.\d{3})*(?:,\d+)?$/;
|
|
341
|
+
const thousandOnlyPattern = /^\d{1,3}(?:\.\d{3})+$/;
|
|
342
|
+
let normalized;
|
|
343
|
+
if (ptPattern.test(s) || thousandOnlyPattern.test(s)) {
|
|
344
|
+
normalized = s.replace(/\./g, '').replace(',', '.');
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
normalized = s.replaceAll(',', '.');
|
|
348
|
+
}
|
|
349
|
+
// Count original decimal places
|
|
350
|
+
const decimalMatch = normalized.match(/\.(\d+)$/);
|
|
351
|
+
if (decimalMatch) {
|
|
352
|
+
const decimalPlaces = decimalMatch[1].length;
|
|
353
|
+
return parseFloat(parseFloat(normalized).toFixed(decimalPlaces));
|
|
354
|
+
}
|
|
355
|
+
return parseFloat(normalized);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Gets an array of regular expressions for matching "less than" patterns in various languages
|
|
359
|
+
* @returns Array of RegExp objects for "less than" pattern matching
|
|
360
|
+
*/
|
|
361
|
+
function getLessThanPatterns() {
|
|
362
|
+
const patterns = [
|
|
363
|
+
/at[eé]\s*([\d\.,]+)/, // Portuguese: "até"
|
|
364
|
+
/inferior\s+a\s+([\d\.,]+)/, // Portuguese: "inferior a"
|
|
365
|
+
/<\s?([\d\.,]+)/, // Universal: "<"
|
|
366
|
+
/menor\s+que\s+([\d\.,]+)/, // Portuguese: "menor que"
|
|
367
|
+
/menos\s+que\s+([\d\.,]+)/, // Portuguese: "menos que"
|
|
368
|
+
/less\s+than\s+([\d\.,]+)/i, // English: "less than"
|
|
369
|
+
/below\s+([\d\.,]+)/i, // English: "below"
|
|
370
|
+
/under\s+([\d\.,]+)/i, // English: "under"
|
|
371
|
+
/menor\s+ou\s+igual\s+a\s+([\d\.,]+)/, // Portuguese: "menor ou igual a"
|
|
372
|
+
/inferior\s+ou\s+igual\s+(?:a\s+)?([\d\.,]+)/, // Portuguese: "inferior ou igual a"
|
|
373
|
+
/less\s+than\s+or\s+equal\s+to\s+([\d\.,]+)/i, // English: "less than or equal to"
|
|
374
|
+
/<=\s*([\d\.,]+)/, // Universal: "<="
|
|
375
|
+
];
|
|
376
|
+
return patterns;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Gets an array of regular expressions for matching "greater than" patterns in various languages
|
|
380
|
+
* @returns Array of RegExp objects for "greater than" pattern matching
|
|
381
|
+
*/
|
|
382
|
+
function getGreaterThanPatterns() {
|
|
383
|
+
const patterns = [
|
|
384
|
+
/superior\s+a\s+([\d\.,]+)/, // Spanish: "superior a"
|
|
385
|
+
/>\s?([\d\.,]+)/, // Universal: ">"
|
|
386
|
+
/maior\s+que\s+([\d\.,]+)/, // Portuguese: "maior que"
|
|
387
|
+
/mais\s+que\s+([\d\.,]+)/, // Portuguese: "mais que"
|
|
388
|
+
/greater\s+than\s+([\d\.,]+)/i, // English: "greater than"
|
|
389
|
+
/above\s+([\d\.,]+)/i, // English: "above"
|
|
390
|
+
/over\s+([\d\.,]+)/i, // English: "over"
|
|
391
|
+
/acima\s+de\s+([\d\.,]+)/, // Portuguese: "acima de"
|
|
392
|
+
/maior\s+ou\s+igual\s+(?:a\s+)?([\d\.,]+)/, // Portuguese: "maior ou igual a"
|
|
393
|
+
/greater\s+than\s+or\s+equal\s+to\s+([\d\.,]+)/i, // English: "greater than or equal to"
|
|
394
|
+
/>=\s*([\d\.,]+)/, // Universal: ">="
|
|
395
|
+
];
|
|
396
|
+
return patterns;
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=extractionUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractionUtils.js","sourceRoot":"","sources":["../../util-ts/extractionUtils.ts"],"names":[],"mappings":"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"}
|