Сопоставление значений между фигурными скобками

У меня есть такая строка: "hello %{name} good %{middle} bye".

Я пытаюсь найти эффективный способ извлечь значения между фигурными скобками, поэтому в идеале у меня должен получиться массив ["name", "middle"].

Используя match, я почти могу туда добраться. Следующие результаты возвращают: ['%{name}', '%{middle}']:

"hello %{name} good %{middle} bye".match(/%{([\w]+)}/g)

Я не уверен, почему в возврат включены символы %, { и }.

Как мне настроить регулярное выражение так, чтобы оно соответствовало только name и middle?

Попробуйте: [..."hello %{name} good %{middle} bye".matchAll(/%{([\w]+)}/g)]

anubhava 26.06.2024 17:43

@anubhava, который возвращает массив массивов

Andrew Parks 26.06.2024 17:51

Почему? См. MDN. Если используется флаг g, будут возвращены все результаты, соответствующие полному регулярному выражению, но группы захвата не включаются.

fdomn-m 26.06.2024 17:55

@AndrewParks: Да, я знаю. Группы захвата начинаются с позиции 1 в каждом элементе.

anubhava 26.06.2024 17:57
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
69
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать именованную группу захвата. В приведенном ниже примере мы назовем его value, а затем извлекем эти значения во время итерации совпадений с регулярным выражением:

let s = "hello %{name} good %{middle} bye"

let r = [...s.matchAll(/%{(?<value>[\w]+)}/g)].map(i => i.groups.value)

console.info(r)

Пытаться

const str = "hello %{name} good %{middle} bye";
const regex = /%\{([\w]+)\}/g;
let matches;
const result = [];

while ((matches = regex.exec(str)) !== null) {
  result.push(matches[1]);
}

console.info(result) // [ 'name', 'middle', 'another', 'example' ]

Что касается вашего вопроса, почему в возврат включены символы %, { и }?

потому что функция match() в JavaScript возвращает всю совпавшую подстроку, включая %{ и }.

Решением этой проблемы было бы использование match[1] (или эквивалента в цикле с exec()), позволяющего получить доступ только к содержимому, заключенному в круглые скобки ( ) в вашем шаблоне регулярного выражения.

Ответ принят как подходящий

Вам нужно изменить выражение регулярного выражения, чтобы оно фиксировало значения внутри фигурных скобок без символов %, { и }, вы можете немного изменить его.

Существующие: /%{([\w]+)}/g => /%\{(\w+)\}/g

См. приведенные ниже примеры:

const str = "hello %{name} good %{middle} bye";
const str1 = "hello %{aaa} good %{bbbb} bye";
const str2 = "hello %{xyz} %{gtr} %{pqr} bye";

const matches = str.match(/%\{(\w+)\}/g);
const matches1 = str1.match(/%\{(\w+)\}/g);
const matches2 = str2.match(/%\{(\w+)\}/g);

const values = matches.map(match => match.slice(2, -1));
const values1 = matches1.map(match => match.slice(2, -1));
const values2 = matches2.map(match => match.slice(2, -1));

console.info(JSON.stringify(values));
console.info(JSON.stringify(values1));
console.info(JSON.stringify(values2));

Кроме того, этого можно достичь и с помощью подхода, не основанного на регулярных выражениях:

const str = "hello %{name} %{world} %{middle} bye";
const str1 = "hello %{aaa} %{bye} %{bbbb} bye";
const str2 = "hello %{xyz} %{gtr} %{pqr} bye";
const startDelimiter = "%{";
const endDelimiter = "}";

function extractValues(input, startDelimiter, endDelimiter) {
    const values = [];
    let startIndex = 0;

    while ((startIndex = input.indexOf(startDelimiter, startIndex)) !== -1) {
        startIndex += startDelimiter.length;
        const endIndex = input.indexOf(endDelimiter, startIndex);
        if (endIndex === -1) {
            break; 
        }
        const value = input.substring(startIndex, endIndex);
        values.push(value);
        startIndex = endIndex + endDelimiter.length;
    }

    return values;
}

const result = extractValues(str, startDelimiter, endDelimiter);
const result1 = extractValues(str1, startDelimiter, endDelimiter);
const result2 = extractValues(str2, startDelimiter, endDelimiter);


console.info(JSON.stringify(result));
console.info(JSON.stringify(result1)); 
console.info(JSON.stringify(result2)); 

Другие вопросы по теме