确认文档的出现次数

时间:2016-05-19 18:20:33

标签: javascript regex

我在创建一个程序时遇到了很大困难,该程序根据我设置的规则检查文档的出现次数。在正则表达式的帮助下,我检查了一些字段,如果存在特定字段,我可以计算它的出现次数,或者我创建一个更深的扫描。这有点令人困惑,我不确切地知道如何解释。

我正在检查文本文件,但为了降低复杂性,我将使用数组。

我有以下数组:

let strings = [
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME2 ID: 10'
];

这是欲望输出:

{
  'NAME' :  { '12': 3 },
  'NAME2':  { '10': 1 }
}

为实现这一目标,我需要做一些检查,所以我想出了以下'MAP':

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  }
];

我很难创建伪代码,我知道这是可以递归完成的,但我被卡住了。最大的问题是因为嵌套,我可以有几个级别的嵌套,不一定是两个。

在过去的几个小时里,我创建了以下代码:

'use strict';

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  }
];

let strings = [
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME2 ID: 10'
];

var _data = {};
for (let string of strings) {

  var root = _data;

  for (let i = 0, length = patterns.length; i < length; i++) {

    let item   = patterns[i];

    let regex  = new RegExp(item.pattern, item.modifier);
    let result = regex.exec(string);

    if (i < patterns.length -1) {
      root = root[result[1]] = {};
    } else {
      root = root[result[1]] = 1;
    }
  }
}

document.body.innerHTML = JSON.stringify({_data});

现在我正在尝试获取最后一部分,计算出现次数,这对屁股来说是一种痛苦。也许递归或生成器可以解决这个问题。

更新 -

重要的是要明白应该使用3,4,5个对象。例如:

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  },
  {
    'pattern'  : 'SOMETHING:\\s*?(\\d+)\\s*',
    'modifier' : ''
  }
];

let strings = [
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME2 ID: 10 SOMETHING: 1010'
];

输出应为:

{
  'NAME': {
    '12': {
      '1010': 3
    }
  },
  'NAME2': {
    '10': {
      '1010': 1
    }
  }
}

3 个答案:

答案 0 :(得分:0)

.preventDefault()

答案 1 :(得分:0)

你可能会喜欢这样。 </head> to </script>对于这些工作非常方便。

Array.prototype.reduce()

所以现在我修改了代码以使用无限制的嵌套属性。我不得不使用两个my invention对象方法var strings = [ 'COMPANY: NAME ID: 12', 'COMPANY: NAME ID: 12', 'COMPANY: NAME ID: 12', 'COMPANY: NAME2 ID: 10' ], reduced = strings.reduce((p,c) => {var co = c.match(/\w+(?=\s*ID)/)[0], id = c.match(/\d+$/)[0]; p[co] ? p[co][id]++ : p[co] = {[id]:1}; return p},{}); document.write("<pre>" +JSON.stringify(reduced,null,2) + "</pre>");Object.prototype.getNestedValue(),它们用于通过动态提供的参数访问和设置/修改嵌套对象属性及其值。提供的最后一个参数是要获取或设置的值。 previopus参数是嵌套属性。对于这些用例,它们是非常方便的方法。所以这就是

Object.prototype.setNestedValue()

答案 2 :(得分:0)

这不是ES6解决方案,但理解起来相对简单:

var strings = [
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME2 ID: 10 SOMETHING: 1010',
  'COMPANY: NAME2 ID: 11 SOMETHING: 1010'
];

var output = {};

for (var i = 0; i < strings.length; i++) {
    var line = strings[i];
    // regex to extract only the values from the current line
    // e.g (NAME, 12, 1010)
    var matches = line.match(/[^\s:]+(?=\s+[^:]+:|$)/g);
    var currentObj = output;
    for (var y = 0; y < matches.length; y++) {
        var match = matches[y];
        var value = currentObj[match];

        // if the value is not the deepest field, 
        //   then create the deeper object to hold the next iteration's values
        // else if it is the deepest field then store the appropriate count
        currentObj[match] = y < matches.length - 1
                              ? value || {}
                              : value ? value + 1 : 1;

        // set up for the next iteration
        currentObj = currentObj[match];
    }
}

console.log(output);

输出:

{
   'NAME':{
      '12':{
         '1010':3
      }
   },
   'NAME2':{
      '10':{
         '1010':1
      },
      '11':{
         '1010':1
      }
   }
}

Demo here
Regex demo