使用正则表达式格式化HTTP标头

3
我希望使用正则表达式格式化我的HTTP头。我已经使用split(' ')和数组操作完成了此操作,但是这次我想使用正则表达式执行此操作。
我想要对这个输入进行操作,它是一个巨大的字符串:
GET /v1/search?q=bob%20dylan&type=artist HTTP/1.1
Host: api.spotify.com
Cache-Control: no-cache
Postman-Token: e2f09f98-f8e0-43f7-5f0e-b16e670399e2

并将其格式化为对象,如下所示:

{ headers: 
   { Host: ' api.spotify.com',
     'Cache-Control': ' no-cache',
     'Postman-Token': ' e2f09f98-f8e0-43f7-5f0e-b16e670399e2' 
   },
  verb: 'GET',
  path: '/v1/search?q=bob%20dylan&type=artist',
  protocol: 'HTTP/1.1' 
}

我知道使用 split 方法会使代码更易读。但我的第一次尝试是使用正则表达式,因为我的目标是提取/格式化字符串。
我知道可以通过正则表达式实现,但这值得吗?大家怎么看?
谢谢您的时间。
3个回答

5
这个对你应该有效:

const data = `GET /v1/search?q=bob%20dylan&type=artist HTTP/1.1
Host: api.spotify.com
Cache-Control: no-cache
Postman-Token: e2f09f98-f8e0-43f7-5f0e-b16e670399e2`

const format = data => {
    const headers = {}
    const result = { headers }
    const regex = /([\w-]+): (.*)/g
    let temp
    while (temp = regex.exec(data)) {
        headers[temp[1]] = temp[2]
    }
    temp = data.match(/(\w+)\s+(.*?)\s+(.*)/)
    result.verb = temp[1]
    result.path = temp[2]
    result.protocol = temp[3]
    return result
}

console.log(format(data))

/([\w-]+): (.*)/g 此正则表达式将匹配任何 header-name: value 并捕获为 ['header-name: value', 'header-name', 'value']

然后我们将其分配给headers对象,其中header-namekeyvaluevalue

最后,我们解析第一行以获取其余信息

工作原理

(\w+) 匹配并捕获一个或多个单词字符
\s+ 匹配1个或多个空格 (.*?)匹配并捕获非贪婪的任何字符 *?
\s+ 直到找到一个或多个空格
(.*) 匹配所有内容(直到行尾)


这里的/(\w+)\s+(.*?)\s+(.*)/是做什么的?我似乎无法在第一个(\w+)之后跟进。它正在寻找1个或多个单词,后面跟着1个或多个空格\s+,然后是(.*?) - kdizzle
我会写解释。 - Maciej Kozieja
我为了与nodejs http风格请求的兼容性问题,为标题键添加了toLowerCase(),但这很有效。另外,httpVersion不是协议,路径最初被称为'url',而动词在node中传统上被称为'method'。 - Master James

2

您可以使用.split()函数和正则表达式\s/,其中.split()返回的数组的前三个元素应该是动词路径协议;在前三个元素上使用.shift()函数,并将结果的剩余部分设置为属性-值对存储在headers对象中,使用当前索引和数组中下一个索引,直到.length不再满足while循环的条件为止。

let getHeaders = headers => {

  let h = headers.split(/\s/);

  let o = {
    verb: h.shift(),
    path: h.shift(),
    protocol: h.shift(),
    headers: {}
  };

  while (h.length) {
    o.headers[h.shift()] = h.shift();
  }
  
  return o
};

var str = `GET /v1/search?q=bob%20dylan&type=artist HTTP/1.1
Host: api.spotify.com
Cache-Control: no-cache
Postman-Token: e2f09f98-f8e0-43f7-5f0e-b16e670399e2`;

console.log(getHeaders(str));


这个例子不太对,但我喜欢你的做法。 GET / HTTP/1.1 Host: 192.168.2.174 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 - Master James

0

这应该可以运行。

搜索方式:

(GET)\s(.+)\s(HTTP\/\d+\.\d+)\n(Host):\s(.+)$\n(Cache-Control):\s(.+)$\n(Postman-Token):\s(.+)$

替换为:

{ headers:    \n\t{ $4 '$5',\n\t  '$6': '$7',\n\t  '$8': '$9'\n\t}, \n\tverb: '$1',\n\tpath: '$2',\n\tprotocol: '$3'\n}

JavaScript 代码:

const regex = /(GET)\s(.+)\s(HTTP\/\d+\.\d+)\n(Host):\s(.+)$\n(Cache-Control):\s(.+)$\n(Postman-Token):\s(.+)$/gm;
const str = `GET /v1/search?q=bob%20dylan&type=artist HTTP/1.1
Host: api.spotify.com
Cache-Control: no-cache
Postman-Token: e2f09f98-f`;
const subst = `{ headers:    \n\t{ \$4 '\$5',\n\t  '\$6': '\$7',\n\t  '\$8': '\$9'\n\t}, \n\tverb: '\$1',\n\tpath: '\$2',\n\tprotocol: '\$3'\\n}`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log(result);

输入:

GET /v1/search?q=bob%20dylan&type=artist HTTP/1.1
Host: api.spotify.com
Cache-Control: no-cache
Postman-Token: e2f09f98-f

输出:

{ headers:    
    { Host 'api.spotify.com',
      'Cache-Control': 'no-cache',
      'Postman-Token': 'e2f09f98-f'
    }, 
    verb: 'GET',
    path: '/v1/search?q=bob%20dylan&type=artist',
    protocol: 'HTTP/1.1'
}

请参见:https://regex101.com/r/3DKEas/4


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接