问一个正则,求指点
apple,city=山东,color=猪皮红 number=100,year=2018 1529074637
怎么匹配这种格式的字符串// 数据样例 myMeasurement,tag1=value1,tag2=value2 fieldKey=fieldValue 1556813561098000000
回答:
摘要
如果要匹配这段字段串,大概会是这样一个正则表达式
const regex = /^\w+(?:,\w+=[\w\u4e00-\u9fa5]+)+\s\w+=\w+(?:,\w+=\w+)*\s\d+$/;const s = "apple,city=山东,color=猪皮红 number=100,year=2018 1529074637";
console.log(regex.test(s)); // true
只考虑了 tag value 有中文的情况,如果 field value 也有可能出现中文,照样改写就行
正则表达式细节
规律其实题主已经总结出来了,由这几个部分组成
myMeasurement
,就是第 1 个逗号之前的部分,需要匹配起始位^
,所以是/^\w+/
接下来是逗号分隔的键值对,如果包含了
myMeasurement
之后的逗号,就很有规律,每一项是/,\w+=\w+/
再考虑到值有中文,所以等号后面的
\w+
改成[\w\u4e00-\u9fa5]+
,结果/,\w+=[\w\u4e00-\u9fa5]+/
这个项需要重复 n 次,所以把这个正则表达式用
(?: )
括起来,缀+
号表示重复/(?:,\w+=[\w\u4e00-\u9fa5]+)+/
- 接下来是一个空格,
\s
,没啥好说的 接下来是另一组键值对,跟之前那组不同,这组没有起始的逗号,所以先加一个没逗号的
/\w+=\w+/
后面再接重复的带逗号的,考虑到只有一组的情况,所以后面的重复用
*
号,而不是+
号/(?:,\w+=\w+/)*
再接空格
\s
,以及一组数字\d+
,并结束字符串$
,所以/\s\d+$/
把上面的各部分组合起来,就是需要的正则表达式
/^\w+(?:,\w+=[\w\u4e00-\u9fa5]+)+\s\w+=\w+(?:,\w+=\w+)*\s\d+$/
取值
使用上面的正则表达式可以判断字符串是否符合格式要求,但要取值会比较难。
如果需要取值,还是直接用代码来写比较好:
// 先按空格分成三段const parts = s.split(" ");
// 第一段按逗号拆分之后,第一部分是 myMeasurement,后面是键值对列表
const [myMeasurement, ...tagList] = parts[0].split(",");
// 把列表中的键值对的键的值拆出来,变成 [键, 值] 这样
// 这里 tagPairs 是多个 [键, 值] 组成的列表(数组),
// 如果需要变成对象(表)直接用 Object.fromEntires(tagPairs) 就行
const tagPairs = tagList.map(t => t.split("=", 2));
// 第二组键值对,如法炮制
const fieldPairs = parts[1].split(",").map(t => t.split("=", 2));
// 按空格分成的第三部分就是那一串数字
const lastNumber = parts[2];
console.log("myMesurement: ", myMeasurement);
console.log("tags: ", tagPairs);
console.log("fields: ", fieldPairs);
console.log("last: ", lastNumber);
// myMesurement: apple
// tags: [ [ 'city', '山东' ], [ 'color', '猪皮红' ] ]
// fields: [ [ 'number', '100' ], [ 'year', '2018' ] ]
// last: 1529074637
回答:
友情提示:提问的方式不对,看不懂你的需求
回答:
这种高度结构化的数据为什么要用正则,直接按特征split就行了。
回答:
^(.*?),(.*?)=(.*?),(.*?)=(.*?)\s+(.*?)=(.*?)\s+(.*?)$
每个括号代表一个分组
以上是 问一个正则,求指点 的全部内容, 来源链接: utcz.com/p/182779.html