匹配分裂边界的键和值

时间:2017-05-26 13:20:25

标签: node.js regex split match form-fields

x = open("file", "rb")
x.read()
'\x02\x00\x00\x00>\x0c\x00\x00\xc5\n\x00\x00'

所以我得到了这个(console.log):

request.on('end', function () {
   if (request.headers.hasOwnProperty('content-type') && request.headers['content-type'].indexOf('boundary=') > -1) {
       var parts = request.headers['content-type'].split('boundary=');
       var boundary = parts[1];
       var splitBody = requestBody.split(boundary);

       console.log(splitBody);
       res.writeHead(200, { "Content-Type": "application/json" });
       res.write(JSON.stringify({ formFields: splitBody }));
   }
   else {
       //bad request
       res.writeHead(400, { "Content-Type": "text/paint" });
       res.write("missing boundary in content-type ");
       }
});

所以基本上我想做的是迭代splitBody并匹配键和值并将其添加到字段数组中。最好的方法是什么?

所以基本上不是这个:

[ '--',
'\r\nContent-Disposition: form-data; name="image"\r\n\r\n/ap.jpg\r\n--',
'\r\nContent-Disposition: form-data; name="name"\r\n\r\nsmth\r\n--',
'--\r\n' ]

它应该是这样的:

'\r\nContent-Disposition: form-data; name="image"\r\n\r\n/ap.jpg\r\n--',

应该添加

1 个答案:

答案 0 :(得分:0)

如果需要将内容部件名称和内容提取为对数组,则仅按边界分割是不够的。您需要详细说明正则表达式以匹配并捕获名称和内容,并迭代通过匹配来提取这些对:

...........................
var boundary = parts[1];
var re = new RegExp("--" + boundary + "\r\n(?:.+name=\"([^\"]+)\".*\r\n)(?:.+\r\n)*\r\n" 
    + "((?:.+\r\n)*.+)(?=\r\n--" + boundary + ")", "g");
var match = re.exec(requestBody);
var fields = [];
while (match) {
    var field = {};
    field[match[1]] = match[2];
    fields.push(field);
    match = re.exec(requestBody);
}
console.log(JSON.stringify({ formFields: fields }))
res.writeHead(200, { "Content-Type": "application/json" });
res.write(JSON.stringify({ formFields: fields }));
...........................

为了解释正则表达式,我为了简单起见假设boundary === "QWERTY"。在这种情况下,正则表达式是:

--QWERTY\r\n(?:.+name="([^"]+)".*\r\n)(?:.+\r\n)*\r\n((?:.+\r\n)*(?:.+))(?=\r\n--QWERTY)

说明:

  1. 实际边界由Content-Type' boundary值组成,前加\r\n--并附加\r\n。因此在正则表达式开头--QWERTY\r\n

  2. 多部分HTTP消息中的每个部分都有一个标题,它是一系列非空字符串((?:.+\r\n)*)紧跟在边界之后并以空字符串结尾((?:.+\r\n)*\r\n

  3. 部分标题的第一行包含name="value"对,它定义了我们感兴趣的名称。这可以与(?:.+name=\"([^\"]+)\".*\r\n)匹配。注意这里的第一个捕获组(([^\"]+)) - 这是我们感兴趣的名称。

  4. 在部分标题之后,我们获得了部分内容,这又是一系列非空行((?:.+\r\n)*),最后一行不包括\r\n(属于下一个边界)。因此,最后一行与.+(非捕获组)匹配,整个部分内容为((?:.+\r\n)*.+)。这也是一个捕获组,因为我们需要这个特定的位是一个字段值。

  5. 我们需要使用边界(?=\r\n--QWERTY)结束我们的部分,但应使用零长度前瞻匹配,以使此边界在下一个正则表达式exec()匹配。

  6. Simplified Node.js demo:https://ideone.com/fQN2hB