匹配 key=(value, value) 格式的正则表达式

Regex to match key=(value, value) format

我正在尝试将包含有关值更改的一些信息的字符串转换为将这些信息分开的对象(或包含它们的数组)。

我收到的字符串是这样的格式,代表变化:

{xRate=(250.0, 260.0), yValue=(1.51, 1.54)}.

我想得到类似的东西

[['xRate', '(250.0, 260.0)'],['yValue', '(1.51, 1.54)']]

或者至少有一个正则表达式可以工作,因为我无法弄明白。

我试过了

/,*\s*(.*)=\s*(.*)/

但它在 test=(23, 34), var=(true , false) 中将第 1 组创建为 test=(23, 34), var,将第 2 组创建为 (true , false)

在此先感谢您的帮助!

(另外,如果你知道任何更好的资源来更好地理解正则表达式,我很乐意看到它,然后我会好好学习哈哈)

const regex = /(\w+)=\((.+?)\)/g;
const str = `{xRate=(250.0, 260.0), yValue=(1.51, 1.54), test=(23, 34), var=(true , false)}`;
while ((match = regex.exec(str)) !== null) {
  console.log(`first group: ${match[1]} and second: ${match[2]}`);
}

针对 OP 问题的正则表达式,正如通过 OP 的示例代码所呈现的那样具体,它确实针对最多两个 key=(value ...) 模式,这些模式用花括号括起来......并且可能看起来像这样...... . /\{\s*(?<key1>[^=\s*]+)\s*=\s*(?<value1>\([^)]+\))\s*(?:,\s*(?<key2>[^=\s*]+)\s*=\s*(?<value2>\([^)]+\))\s*)?\}/g ...但也同样匹配...

  • { key=(value), key=(value, value, ...) }
  • { key=(value, value), key=(value) }
  • { key=(value, value) }
  • { key=(value) }

const sampleText = `{xRate=(250.0, 260.0)  ,  yValue  =(1.51, 1.54)} ... { xRate  =  (250.0, 260.0)  }
... { yValue=(1.51, 1.54) } ... {  xRate = ( 250.0 , 260.0), yValue=(1.51, 1.54) }`;

// [https://regex101.com/r/gJoFH7/1]
const regXKeyValueMaxTwice = (/\{\s*(?<key1>[^=\s*]+)\s*=\s*(?<value1>\([^)]+\))\s*(?:,\s*(?<key2>[^=\s*]+)\s*=\s*(?<value2>\([^)]+\))\s*)?\}/g)

const keyValueToArrayEntryFormat = (match, key1, value1, key2, value2) =>
  (key2 && value2)
    ? `[['${ key1 }', '${ value1 }'], ['${ key2 }', '${ value2 }']]`
    : `[['${ key1 }', '${ value1 }']]`;

console.log(
  sampleText + '\n\n => \n\n',

  sampleText.replace(regXKeyValueMaxTwice, keyValueToArrayEntryFormat)
);

console.log('\nadditional regX logging ...\n\n');

console.log([
  ...sampleText.matchAll(regXKeyValueMaxTwice)
  ]
);
console.log([
  ...sampleText.matchAll(regXKeyValueMaxTwice)
  ].map(({ groups }) => groups)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

但是更通用的方法可以自由处理无限数量的 key = (value[, value[, ...]])(子)模式序列,这些序列都被花括号括起来,例如 ... { key=(value), key=(value, value),.. key=(value, value) ... }.

因此,为了将上面的 format/pattern 转换成... [["key", "(value)"], ["key", "(value, value)"],.. ["key", "(value, value)"] ...] 正则表达式不能再预测这种基本模式的 frequency/occurrence,但它可以捕获额外的允许稍后指示此类模式是否由 { 打开或由 , 继续或由 } 终止的标志。

一个更简单、更简洁的正则表达式可能看起来像这样……/(?<sequenceFlag>[{,])\s*(?<key>\w+)\s*=\s*(?<value>\([^)]+\))\s*(?<terminatingFlag>\}?)/g……然后相应替换的实现可能接近于那个……

const sampleText = `{xRate=(250.0, 260.0)  ,  yValue  =(1.51, 1.54)} ... { xRate  =  (250.0, 260.0)  }

... { yValue=(1.51, 1.54) } ... {  xRate = ( 250.0 , 260.0), yValue=(1.51, 1.54) }

{ xRate = ( 250.0, 260.0 ) ,yValue=(1.51,1.54), zItem =( foo, bar,baz) } ... {xRate=(250.0,260.0)}`;

// [https://regex101.com/r/gJoFH7/2]
const regXKeyValueTemplate = (/(?<sequenceFlag>[{,])\s*(?<key>\w+)\s*=\s*(?<value>\([^)]+\))\s*(?<terminatingFlag>\}?)/g)

const keyValueToArrayEntryFormat = ((match, sequenceFlag, key, value, terminatingFlag) => {
  const concatEntry = (sequenceFlag === '{') && '[[' || ', [';
  const closeSequence = (terminatingFlag === '}') && ']' || '';
  return `${ concatEntry }'${ key }', '${ value }']${ closeSequence }`;
});

console.log(
  sampleText + '\n\n => \n\n',

  sampleText.replace(regXKeyValueTemplate, keyValueToArrayEntryFormat)
);

console.log('\nadditional regX logging ...\n\n');

console.log([
  ...sampleText.matchAll(regXKeyValueTemplate)
  ]
);
console.log([
  ...sampleText.matchAll(regXKeyValueTemplate)
  ].map(({ groups }) => groups)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

正则表达式来源: