【问题标题】:Iterate a string with Regex and JS使用 Regex 和 JS 迭代字符串
【发布时间】:2023-03-19 07:04:02
【问题描述】:

我有一组结构化数据到一个字符串中,我需要通过 Javascript 中的常规 espression 对其进行迭代。

这是数据示例:

|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4

我需要解析它们并创建一个结构化对象(或数组),如下所示:

myObject.KEY1 = "VALUE 1"
myObject.KEY2 = "VALUE 2"
myObject.KEY3 = "OTHER VALUE WITH ANY CHARACTER LIKE SPACES, AND WHAT YOU WANT"
myObject.KEY4 = "VALUE4"

我已经有了那个简单的正则表达式的键:[|](.+?)[|],但我不知道如何遍历它们以及它们各自的值。

【问题讨论】:

  • 如果允许您在数据中使用分隔符|,那么您必须有一些方法可以将其转义。绝对没有办法区分|PIPES| 不是一个新键,后面跟着一个新值。即使键的格式非常严格,我总是可以在数据中放入 看起来 像键的东西。例如|KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, \|PIPES\| AND WHAT YOU WANT
  • 你是对的。我查看了数据,并没有出现这种情况。所以忘记了元管道问题;)
  • @Pennywise83 什么样的来源以这种格式提供数据?
  • 为什么是正则表达式?这似乎是一个简单的字符串操作问题。

标签: javascript regex key-value


【解决方案1】:

我将假设一个键由表达式\|KEY[0-9]+\| 定义,因为这是包含|KEY1||KEY4| 同时排除|PIPES| 的最简单方法。

如果您的目标是使用循环和正则表达式匹配,而不是使用单个复杂的正则表达式或使用 indexOf() 等函数进行实际解析,那么 这可以通过负前瞻来完成

var x = "|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4";

var map = {};

while(x.length > 0) {
    var key = x.match(/\|KEY[0-9]+\|/)[0];
    x = x.substr(key.length);
    var value = x.match(/(.(?!\|KEY[0-9]+\|))*/)[0];
    x = x.substr(value.length);
    map[key] = value;
}

alert(JSON.stringify(map, null, 4));

http://jsfiddle.net/eyL7yhwr/

【讨论】:

    【解决方案2】:

    这样就可以了。

    //using regex
    var keyString = "|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4"
    var cases = keyString.match(/[^|]+/g)
    var myObject = {};
    if (cases.length > 0)
      {
         for (var i = 0; i < cases.length; i += 2)
         {
           myObject[cases[i].toString()] = cases[i+1].trim();
         }
      }
      
      document.write(JSON.stringify(myObject));

    【讨论】:

    • 问题中的示例输出显示“|PIPES|”不应该是关键之一,所以这个答案是不正确的(除非他改变了对这个要求的想法)。
    • @Ixrec "你是对的。我查看了数据,没有出现这种情况。所以忘记了元管道问题;)" OP。
    • 回想起来很难说他是否真的想要“|PIPES|”是否是关键,所以我只会 +1,我们称之为平局。
    【解决方案3】:

    你可以这样做:

    var s = "|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4";
    
    s.match(/\|(KEY\d+)\|.*?(?=\|KEY\d|$)/g).reduce(function (res, v) { 
      var match = v.match(/(KEY\d+)\|(.*?)\s*$/);
      res[match[1]] = match[2];
      return res;
    }, {})

    另一个更简单的解决方案:

    var s = "|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4";
    
    var v, res = {}, match = s.match(/\s*\|KEY\d+\|\s*|.+?(?=\s*\|KEY\d|$)/g);
    while(v = match.shift()) 
      res[v.replace(/^[\s|]*|[\s|]*$/g, '')] = match.shift();

    【讨论】:

      【解决方案4】:

      exec/[^|]+/g 之类的东西会给你一个很好的数组。

      var str = "|KEY1|VALUE 1 |KEY2| VALUE 2 |KEY3| OTHER VALUE WITH ANY CHARACTER LIKE SPACES, |PIPES| AND WHAT YOU WANT |KEY4| VALUE4";
      
      var re = /[^|]+/g;
      
      var arr = [];
      
      while ((arr = re.exec(str)) !== null){
        console.log(arr[0].trim());
      }
      

      fiddle

      这里比其他一些正则表达式要简单一些,而且我认为它更具可读性。我还使用了trim(),如果你想在IE9之前支持,你必须使用the polyfill

      【讨论】:

        猜你喜欢
        • 2014-02-07
        • 1970-01-01
        • 2013-01-23
        • 2019-04-30
        • 1970-01-01
        • 2014-04-21
        • 1970-01-01
        • 2021-01-13
        • 1970-01-01
        相关资源
        最近更新 更多