有没有比非常写匹配更好的方法?

Is there better way than write match very much?

, 我有这个代码

let key = N001DSC29MC22HC22DD04MD09YD21
function get(key) {
  let res = {};
  res.matchNumber = key.match(/(?<=N)\d{3}/g);
  res.matchSeconds = key.match(/(?<=DSC)\d{2}/g);
  res.matchMinutes = key.match(/(?<=MC)\d{2}/g);
  res.matchHours = key.match(/(?<=HC)\d{2}/g);
  res.matchDay = key.match(/(?<=DD)\d{2}/g);
  res.matchMonth = key.match(/(?<=MD)\d{2}/g);
  res.matchYear = key.match(/(?<=YD)\d{2}/g);
  res.title = JSON.parse(localStorage.getItem(key)).title;
  res.description = JSON.parse(localStorage.getItem(key)).description;
  Object.keys(res).forEach(key => {
    if (! res[key]) delete res[key]
    if (Array.isArray(res[key])) res[key] = res[key].join('')
  })
  return res;
}
get(key)

如您所见,我的代码不干净,有更好的方法来实现相同的功能。我真的很努力,我不能做得更好

我的意思是使用 REGEXP 更好 match 非常像这样

在我看来,您可以将对象字段的初始化与对象的创建内联,foreach 不是最好的副作用,尝试制作对象 const 并使用类似的东西过滤和减少:

// the snipped won't work because of the sandbox policy
let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
  const res = {
    matchNumber : key.match(/(?<=N)\d{3}/g),
    matchSeconds : key.match(/(?<=DSC)\d{2}/g),
    matchMinutes : key.match(/(?<=MC)\d{2}/g),
    matchHours : key.match(/(?<=HC)\d{2}/g),
    matchDay : key.match(/(?<=DD)\d{2}/g),
    matchMonth : key.match(/(?<=MD)\d{2}/g),
    matchYear : key.match(/(?<=YD)\d{2}/g),
    title : JSON.parse(localStorage.getItem(key)).title,
    description : JSON.parse(localStorage.getItem(key)).description,
  };
  return Object.entries(res)
    .filter(([k]) => k)
    .reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)

但是,您实际上可以避免创建 res 对象并从另一个数据结构开始(Object.entries 将 return 的数据结构)

let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
  return [
    ['matchNumber' , key.match(/(?<=N)\d{3}/g)],
    ['matchSeconds' , key.match(/(?<=DSC)\d{2}/g)],
    ['matchMinutes' , key.match(/(?<=MC)\d{2}/g)],
    ['matchHours' , key.match(/(?<=HC)\d{2}/g)],
    ['matchDay' , key.match(/(?<=DD)\d{2}/g)],
    ['matchMonth' , key.match(/(?<=MD)\d{2}/g)],
    ['matchYear' , key.match(/(?<=YD)\d{2}/g)],
    ['title' , JSON.parse(localStorage.getItem(key)).title],
    ['description' , JSON.parse(localStorage.getItem(key)).description],
  ].filter(([k]) => k).reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)

使用 Object.fromEntries 创建对象,其中的条目从 Object.entries 过滤和映射看起来更清晰一些。

console.log(get(`N001DSC29MC22HC22DD04MD09YD21`));

function get(key) {
 return Object.fromEntries(
  Object.entries({
      matchNumber: key.match(/(?<=N)\d{3}/g),
      matchSeconds: key.match(/(?<=DSC)\d{2}/g),
      matchMinutes: key.match(/(?<=MC)\d{2}/g),
      matchHours: key.match(/(?<=HC)\d{2}/g),
      matchDay: key.match(/(?<=DD)\d{2}/g),
      matchMonth: key.match(/(?<=MD)\d{2}/g),
      matchYear: key.match(/(?<=YD)\d{2}/g),
      // mockup for not working localStorage in sandbox   
      title: `sometitle`,
      description: `somedescription`,
    })
    // filter only key-value pairs with a value
    .filter( ([key, value]) => value )
    // map to values with joined Arrays if applic.
    .map( ([key, value]) => 
      [key, Array.isArray(value) ? value.join('') : value ] )
  );
}

备选方案,来自一个 raw string 的标签和正则表达式,使用一个 reducer 创建对象。

const getValuesFromKey = key => ({ 
    ...String.raw`
      ID::(?<=N)\d{3}
      Seconds::(?<=DSC)\d{2}
      Minutes::(?<=MC)\d{2}
      Hours::(?<=HC)\d{2}
      Day::(?<=DD)\d{2}
      Month::(?<=MD)\d{2}
      NoMatch::(?<=NOTHING)\d{2} // won't match anything
      Years::(?<=YD)\d{2} // will find two years `
    .split(`\n`)
    .reduce( (acc, line) => {
      line = line.replace(/\/\/.*$/, ``).trim();
      const [label, re] = line && line.split(`::`);
      const match = re && key.match(new RegExp(re, `g`));
      return match ? {...acc, [[label]]: match.join(` and `)} : acc;
    }, {}),
    Title: `someTitle`,
    Description: `someDescription` });

console.log(getValuesFromKey(`N001DSC29MC22HC22DD04MD09YD21YD45`));
//                                                         ^ extra value

或使用named capture groups. See this stackblitz project