javascript - 使用正则表达式将文本解析为对象

标签 javascript regex

我使用的 API 返回以下格式的文本:

#start
#p 12345 foo
#p 12346 bar
#end
#start
#p 12345 foo2
#p 12346 bar2
#end

我的解析函数:

function parseApiResponse(data) {

    var results = [], match, obj;

    while (match = CST.REGEX.POST.exec(/(#start)|(#end)|#p\s+(\S+)\s+(\S+)/ig)) {

        if (match[1]) {           // #start
            obj = {};

        } else if (match[2]) {    // #end
            results.push(obj);
            obj = null;           // prevent accidental reuse 
                                  // if input is malformed

        } else {                  // #p something something
            obj[match[3]] = match[4];
        }
    }

    return results;
}

这会给我一个看起来像这样的对象列表:

[{ '12345': 'foo', '12346': 'bar'}, /* etc... */]

但是,如果一行是这样格式化的

#start
#p 12345
#p 12346 bar
#end

该行实际上是 #p 12345\n 而我的 match[4] 将包含下一行的 #p

如何调整模式以适应这种情况?

最佳答案

假设您每行有一个 #start#end#p 元素,您可以让您的正则表达式知道这一点并且添加一个额外的非捕获组以指示行中的最后一个 \s+(\S+) 是可选的:

/(#start)|(#end)|#p\s+(\S+)(?:\s+(\S+))?$/igm

(?: ) 表示“将其视为一个组,但不捕获它匹配的模式”(因此它不会在 match).该组后面的 ? 表示“该组是可选的,可能匹配也可能不匹配模式中的任何内容”。紧随其后的 $m 标志一起匹配行尾。

您还可以通过使用 * 而不是 + 量词来避免 (?: ) 欺骗,意思是“匹配零次或多次”:更改 \s+(\S+)\s*(\S*)。这会产生副作用,即数字和它后面的数据之间的空格现在是可选的。

我会重写正则表达式并重构代码,如下所示:

while (match = CST.REGEX.POST.exec(/^#(start|end|p)(?:\s+(\d+)(?:[^\S\r\n]+([^\r\n]+))?)?$/igm)) {
  switch (match[1]) {
    case 'start':
      obj = {};
      break;
    case 'end':
      results.push(obj);
      obj = null;
      break;
    case 'p':
      obj[match[2]] = match[3];
      break;
  }
}

我喜欢在一个捕获组中捕获 startendp,这样我就可以在 switch声明。我在这里使用的正则表达式版本更具辨别力(希望 #p 后面的标记为数字)并且更宽容(允许 #p< 上的最后一个标记 行包含任何非换行空格,例如 #p 1138 this is only a test).

关于javascript - 使用正则表达式将文本解析为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22966982/

相关文章:

带有一个日期和可选的第二个日期的文件名的 Java 正则表达式

regex - 正则表达式的局限性?

java - 使用java从字符串中删除双字母

regex - 使用正则表达式匹配powershell中的括号

javascript - 在 PHP 中为 Javascript 生成小而有效的变量名的算法

javascript - 多用户问题 Node.js

Javascript 对象字面范围问题?

php - 如何使用 PHP preg_replace 链接 Twitter 用户名?

javascript - 从 div 中删除一个类

javascript - 如何定义 Redux Actions 的 Flow 类型?