регулярное выражение для поиска пар в массиве

1

Я хотел бы проанализировать эту строку:

[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]

Чтобы иметь ключевое значение (JSON)

{
"abc.d.2": "mcnv.3.we",
"abec.d.2: "mcnv.4.we",
"abhc.d.2": "mcnv.5.we"
}

Сначала я хотел бы проверить, может ли строка разбираться, чтобы сделать ключ => значение. Как проверить строку, если она содержит пары?

Спасибо

  • 0
    Я попробовал это: ([. *?,. *?]) Но недостаточно иметь пары :( Кстати: я никогда не задаю вопрос, если не пробовал несколько часов назад
  • 0
    Ожидаете ли вы больше уровней вложенности?
Показать ещё 7 комментариев
Теги:

4 ответа

2
Лучший ответ

Вы можете попробовать что-то вроде этого:

Подход 1:

Идея:

  • Обновите регулярное выражение, чтобы иметь более конкретные символы. В вашем случае, буквенно-цифровой и период.
  • Получите все соответствующие элементы из строки.
  • Все нечетные значения являются ключами, а совпадения - значениями.
  • Перебирайте совпадения и создайте объект.

const str = "[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]";
const matches = str.match(/[\w\.\d]+/gi);

const output = {};

for(var i = 0; i< matches.length; i+=2) {
  output[matches[i]] = matches[i+1];
}

console.log(output)

Подход 2:

Идея:

  • Напишите регулярное выражение для записи каждой отдельной группы: [...:...]
  • Затем устраните фигурные скобки [ и ].
  • Разбивает строку с помощью запятой ,.
  • Первая часть - ваш ключ. Во-вторых, ваша ценность.

const str = "[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]";
const matches = str.match(/\[([\w\d\.,]*)\]/gi);
const output = matches.reduce((obj, match) => {
  const parts = match.substring(1, match.length - 1).split(',');
  obj[parts[0]] = parts[1];
  return obj;
}, {})

console.log(output)

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

const str = "[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]";
const matches = str.match(/\[([\w\d\.,]*)\]/gi);
const output = matches.reduce((obj, match) => {
  const parts = match.substring(1, match.length - 1).split(',');
  obj.set(...parts)
  return obj;
}, new Map())

for (const [k, v] of output.entries()) {
  console.log('Key: ${k}, value: ${v}')
}
  • 0
    Очень хорошо. Это намного лучше, чем то, что у меня есть, но я хотел бы знать, соответствует ли оно парам в регулярном выражении. Вы имеете дело с этим в цикле
  • 0
    @IsraGab, ты тоже можешь это сделать. Но это займет больше профессии. Вы можете иметь регулярное выражение для сопоставления текста между [] а затем разделить его, используя строку. Если вы хотите, я могу добавить фрагмент завтра.
Показать ещё 4 комментария
1

Мое кодирование для гольфа...

const parse = (str) => {
    let obj = {};
    str.replace(
        /\[([^\[,]+),([^\],]+)\]/g,
        (m, k, v) => obj[k] = v
    );
    return obj;
};

Преимущества:

  • Более допустимый произвольный символ
  • Больше Толерантность отсутствующих значений
  • Избегает одноразовых объектов для GC

Недостатки:

  • Более правдоподобные произвольные символы!
  • Это не правильный парсер...
  • Не имеет контекста, просто [key, val]

Я действительно хотел опубликовать следующее в качестве своего ответа... но я думаю, что это вызовет у меня проблемы: P

const parse=(str,obj={})=>
!str.replace(/\[([^\[,]+),([^\],]+)\]/g,(m,k,v)=>obj[k]=v)||obj;
1

Разбирайте массив как JSON, итерации по массиву, добавляя записи к целевому объекту, когда вы идете, следите за дублирующимися ключами:

let dict_target = {}; // The target dictionary, 
let src, arysrc, proceed = false;

try {
    src = "[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]"
                  .replace(/,/g, '","')
                  .replace(/\]","\[/g, '"],["')
                  .replace(/^\[\[/, '[["')
                  .replace(/\]\]$/, '"]]')
             ;
    arysrc = JSON.parse(src);
    proceed = true; // Could parse the data, can carry on with processing the data
} catch (e) {
    console.log('Source data unparseable, error '${e.message}'.');
} 

if (proceed) {
    arysrc.forEach ( (a_item, n_idx) => {
        if (dict_target.hasOwnProperty(a_item[0])) {
           // add any tests and processing for duplicate keys/value pairs here  
           if (typeof dict_target[a_item[0]] === "string") {
               dict_target[a_item[0]] = [ dict_target[a_item[0]] ];
           }
           dict_target[a_item[0]].push(a_item[1]);
        }
        else {
           dict_target[a_item[0]] = a_item[1];
        }
    });
 } // if -- proceed
  • 0
    У меня нет ' вы добавили в строку. Я не могу использовать функцию JSON.parse. Кроме того, я не хочу повторять объект, но знает, могу ли я разобрать его раньше
  • 0
    @IsraGab Я исправил решение. Если разбор пройдет успешно, вы будете знать, что можете его проанализировать. Вы можете проверить это перед использованием регулярного выражения. Использование их в качестве замены для анализаторов имеет тенденцию усложнять и усложнять их обслуживание, поэтому я постараюсь избежать этого варианта использования, но ваши настройки, конечно, могут отличаться.
Показать ещё 7 комментариев
0

Здесь код, который сначала проверяет строку и выводит результат. Совсем не оптимально, но задача просто прекрасна.

var string = '[[abc.d.2,mcnv.3.we],[abec.d.2,mcnv.4.we],[abhc.d.2,mcnv.5.we]]';
var result = (/^\[(\[.*\..*\..*\,.*\..*\..*\]\,)*\[(.*\..*\..*\,.*\..*\..*)\]\]$/g).exec(string);
if (result) {
  var r1 = result[1].replace(/\[|\]/g, '').split(',');
  var r2 = result[2].split(',');
  var output = {};

  for (var i = 0; i < r1.length -1; i +=2) {
    output[r1[i]] = r1[i+1];
  }
  output[r2[0]] = r2[1];

  console.log(output);
} else {
  console.log('invalid string');
}
  • 0
    Ваше регулярное выражение довольно тяжело с этими жадными .* .
  • 1
    Да, я знаю. Вот почему я упомянул, что это не оптимальное решение :) Производительность не будет иметь значения, если вы анализируете небольшую строку. Это был бы другой случай парсинга огромных CSV с такой логикой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню