Финальный вариант
Результат всех доработок по задаче парсинга строки. Его можно брать с собой на любой проект.
v2: С вариативностью типов значений для парсинга
export const getExtractedValues = ({
tested, expectedKey, valueType
}: {
tested: string[];
expectedKey: string;
valueType: 'number' | 'string';
}): string[] => {
const results: string[] = [];
for (let i = 0, max = tested.length; i < max; i++) {
const t = tested[i];
let regex
switch (valueType) {
case 'number':
regex = new RegExp(`\\[${expectedKey}=(?<value>\\d+)\\]`, 'g')
break
case 'string':
default:
regex = new RegExp(`\\[${expectedKey}=(?<value>.*?)\\]`, 'g')
break
}
for (const n of t.matchAll(regex))
if (n?.groups) results.push(n.groups.value)
}
return results;
}Tests
import { getExtractedValues } from './getExtractedValues';
describe('Тестирование получения значения из строки', () => {
test('case 1: Простой успешный кейс', async () => {
const testedValue = getExtractedValues({
tested: ['[days=1]'],
expectedKey: 'days',
valueType: 'number',
});
const expectedValue = ['1'];
expect(testedValue).toEqual(expectedValue);
});
test('case 2: Простой успешный кейс', async () => {
const testedValue = getExtractedValues({
tested: ['[days=11]'],
expectedKey: 'days',
valueType: 'number',
});
const expectedValue = ['11'];
expect(testedValue).toEqual(expectedValue);
});
test('case 3', async () => {
const testedValue = getExtractedValues({
tested: ['[DAYS_LEFT=777]'],
expectedKey: 'DAYS_LEFT',
valueType: 'number',
});
const expectedValue = ['777'];
expect(testedValue).toEqual(expectedValue);
});
test('case 4', async () => {
const testedValue = getExtractedValues({
tested: ['[days-left=11]'],
expectedKey: 'days-left',
valueType: 'number',
});
const expectedValue = ['11'];
expect(testedValue).toEqual(expectedValue);
});
test('case 5', async () => {
const testedValue = getExtractedValues({
tested: ['[days-@-left=11]'],
expectedKey: 'days-@-left',
valueType: 'number',
});
const expectedValue = ['11'];
expect(testedValue).toEqual(expectedValue);
});
test('case 6', async () => {
const testedValue = getExtractedValues({
tested: ['[days-left=11]'],
expectedKey: 'days-left-impossible',
valueType: 'number',
});
const expectedValue: string[] = [];
expect(testedValue).toEqual(expectedValue);
});
test('case 7', async () => {
const testedValue = getExtractedValues({
tested: ['[days-left-impossible=11]'],
expectedKey: 'days-left',
valueType: 'number',
});
const expectedValue: string[] = [];
expect(testedValue).toEqual(expectedValue);
});
test('case 8', async () => {
const testedValue = getExtractedValues({
tested: ['[SPECIAL_MSG=Just a moment, plz]'],
expectedKey: 'SPECIAL_MSG',
valueType: 'string',
});
const expectedValue: string[] = ['Just a moment, plz'];
expect(testedValue).toEqual(expectedValue);
});
test('case 9', async () => {
const testedValue = getExtractedValues({
tested: ['[SPECIAL_MSG=Just a moment, plz]', '[SPECIAL_MSG=message 2]'],
expectedKey: 'SPECIAL_MSG',
valueType: 'string',
});
const expectedValue: string[] = ['Just a moment, plz', 'message 2'];
expect(testedValue).toEqual(expectedValue);
});
});Рабочие моменты
Далее можно не читать, оставил как черновики и общение с коллегами.
v1: Поиск числа
export const getExtractedValues = ({
tested, expectedKey
}: {
tested: string[];
expectedKey: string;
}): string[] => {
const results: string[] = [];
for (let i = 0, max = tested.length; i < max; i++) {
const t = tested[i];
const regex = new RegExp(`\\[${expectedKey}=(?<value>\\d+)\\]`, 'g');
// eslint-disable-next-line no-restricted-syntax
for (const n of t.matchAll(regex)) {
if (n?.groups) { results.push(n.groups.value); }
}
}
return results;
};Скобочные группы https://learn.javascript.ru/regexp-groups#itogo
Именованные группы https://learn.javascript.ru/regexp-groups#imenovannye-gruppy
Метод
str.matchвозвращает скобочные группы только без флага g. Методstr.matchAllвозвращает скобочные группы всегда.
Если нужно искать несколько таких вхождений, то нужно использовать matchAll с последующей итерацией:
const key = 'days';
const strings = ['[days=1]', '[days=9999]', '[days=7] [days=555]'];
const regex = new RegExp(`\\[${key}=(\\d+)\\]`, 'g');
for (const s of strings) {
for (const num of s.matchAll(regex)) {
console.log(s, num);
}
}node day-key.js
[days=1] [ '[days=1]', '1', index: 0, input: '[days=1]', groups: undefined ]
[days=9999] [
'[days=9999]',
'9999',
index: 0,
input: '[days=9999]',
groups: undefined
]
[days=7] [days=555] [
'[days=7]',
'7',
index: 0,
input: '[days=7] [days=555]',
groups: undefined
]
[days=7] [days=555] [
'[days=555]',
'555',
index: 9,
input: '[days=7] [days=555]',
groups: undefined
]