@whiteslove/parsing-lexicon 0.10.8 → 0.10.9
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/package.json +1 -1
- package/src/hiring-skills.js +4 -1
- package/src/hiring-source-semantics.js +2 -2
- package/src/money-core.js +4 -1
- package/src/money.js +10 -2
package/package.json
CHANGED
package/src/hiring-skills.js
CHANGED
|
@@ -368,8 +368,11 @@ export function canonicalSkillName(value) {
|
|
|
368
368
|
return CANONICAL_BY_ALIAS.get(normalized) ?? extractSkillNames(normalized)[0]
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
+
const PAY_BONUS_KPI_RE = /(?:\+|plus|плюс)\s*(?:%\s*\/?\s*)?kpi(?![\p{L}\p{N}_])/giu
|
|
372
|
+
|
|
371
373
|
export function extractSkillDetails(text) {
|
|
372
|
-
|
|
374
|
+
// "+ KPI" / "plus KPI" after a pay figure is a bonus scheme, not a skill.
|
|
375
|
+
const normalized = normalizeSkillText(cleanHiringSourceText(text).replace(PAY_BONUS_KPI_RE, ' '))
|
|
373
376
|
const found = []
|
|
374
377
|
const names = new Set()
|
|
375
378
|
for (const { definition, patterns } of COMPILED_SKILLS) {
|
|
@@ -76,8 +76,8 @@ export function extractJobStructuredField(value, key, maxLength = 220) {
|
|
|
76
76
|
return extractField(value, JOB_FIELD_TERMS[key], FIELD_EXTRA_ALIASES.job[key] || [], maxLength);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const INLINE_VACANCY_HEADING_RE =
|
|
80
|
-
const SHARED_HIRING_CONTACT_RE = /(?:✈️?\s*Telegram\s*:|📞\s*Контакт\s
|
|
79
|
+
const INLINE_VACANCY_HEADING_RE = /(?:✔️?|▶️?)\s*([A-ZА-ЯЁЎҚҒҲІЇЄ][A-ZА-ЯЁЎҚҒҲІЇЄ\s()\/-]{2,100}?(?:\s*\([^)\n]{1,30}\))?)(?=\s*(?:[:•⏳✔▶📍✈📞💰]|$))/gu;
|
|
80
|
+
const SHARED_HIRING_CONTACT_RE = /(?:✈️?\s*Telegram\s*:|📞\s*Контакт\s*:|👍\s*ГРАФИК\s+РАБОТЫ)/iu;
|
|
81
81
|
|
|
82
82
|
/** Split a multi-vacancy source post into role-local blocks and shared context. */
|
|
83
83
|
export function splitHiringVacancyEntries(value) {
|
package/src/money-core.js
CHANGED
|
@@ -22,7 +22,10 @@ export const MONEY_SCALE_PATTERN = 'k|к|тыс\\.?|тысяч(?:а|и)?|тис\
|
|
|
22
22
|
// present at all) would stop matching, since "до" doesn't satisfy the
|
|
23
23
|
// boundary either.
|
|
24
24
|
export const MONEY_RANGE_RE = new RegExp(`(${MONEY_NUMBER_PATTERN})\\s*(?:(${MONEY_SCALE_PATTERN})(?=$|[^\\p{L}\\p{N}_]))?\\s*(?:-|–|—|до|to|bis|dan\\s+gacha)\\s*(${MONEY_NUMBER_PATTERN})\\s*(?:(${MONEY_SCALE_PATTERN})(?=$|[^\\p{L}\\p{N}_]))?`, 'iu');
|
|
25
|
-
|
|
25
|
+
// Boards often glue the currency to the number ("10 000 000сум"); without this
|
|
26
|
+
// the boundary check fails on the full number and backtracks to "10 000".
|
|
27
|
+
const ATTACHED_CURRENCY = "сум|сўм|so['’ʻʼ`]?m|som|uzs|usd|eur|rub|руб|грн|kzt|kgs";
|
|
28
|
+
export const MONEY_SINGLE_RE = new RegExp(`(${MONEY_NUMBER_PATTERN})\\s*(${MONEY_SCALE_PATTERN})?(?=$|[^\\p{L}\\p{N}_]|(?:${ATTACHED_CURRENCY})(?![\\p{L}\\p{N}_]))`, 'giu');
|
|
26
29
|
|
|
27
30
|
export function parseNumericAmount(raw) {
|
|
28
31
|
let value = String(raw || '').replace(/\u00a0/g, ' ').trim();
|
package/src/money.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { findPhoneLikeSpans } from './contact.js';
|
|
1
|
+
import { findPhoneLikeSpans, parsePhoneNumbers } from './contact.js';
|
|
2
2
|
import { aliasesOf, findCanonical, normalizeUnicode } from './normalization.js';
|
|
3
3
|
import {
|
|
4
4
|
CURRENCY_SYMBOL_CANDIDATES,
|
|
@@ -56,7 +56,15 @@ function hasModifier(text, key) {
|
|
|
56
56
|
function protectedPhoneSpans(text) {
|
|
57
57
|
return findPhoneLikeSpans(text).filter((span) => {
|
|
58
58
|
const prefix = text.slice(Math.max(0, span.start - 32), span.start);
|
|
59
|
-
|
|
59
|
+
if (CONTACT_MARKER_RE.test(prefix)) return true;
|
|
60
|
+
// A label-less international number ("998 953 506 090", typically scraped
|
|
61
|
+
// into a pay field) is a contact, not a 12-digit salary. Require a valid
|
|
62
|
+
// E.164 number of 11+ digits so ordinary grouped salaries stay money.
|
|
63
|
+
// A "998 95… - 998 95…" pair is merged into one span, so test each part.
|
|
64
|
+
return span.raw.split(/\s*[-–—]\s*/u).some((part) => {
|
|
65
|
+
const digits = part.replace(/\D/g, '');
|
|
66
|
+
return digits.length >= 11 && parsePhoneNumbers(`+${digits}`).length > 0;
|
|
67
|
+
});
|
|
60
68
|
});
|
|
61
69
|
}
|
|
62
70
|
|