我正在尝试从编码的二维条形码中提取数据。提取部分工作正常,我可以在文本输入中获取值。
例如,解码后的字符串是
]d20105000456013482172012001000001/:210000000001
基于以下规则(无法获得正确的表格 Markdown ,因此附上图片),我尝试从上述字符串中提取子字符串。
我要提取的子字符串:
05000456013482(位于分隔符01之后)
201200(位于分隔符 17 之后)
00001(位于分隔符 10 之后)
0000000001(位于分隔符 21 之后)
P.S -> 原始字符串(]d2
)中的前 3 个字符始终相同,因为它只是简单地表示解码方法。
现在有一些怪癖:
1) 分隔符10
之后的字母数量不固定。因此,在上面给出的示例中,即使它是 00001
,它也可能是 001
。同样,分隔符21
之后的字母数量也不固定,并且可以具有不同的长度。
对于不同长度的分隔符,我添加了一个常量 /:
来确定扫描手持设备后编码何时结束。
现在,我在分隔符 10 之后查找 /:
并提取字符串,直到它到达 /:
或 EOL,找到分隔符 21 并删除该字符串,直到它出现为止点击 /:
或 EOL
2) 分隔符01
和17
之后的字母数量始终是固定的(分别为14个字母和6个字母),如表所示。
注意:分隔符的位置可能会改变。换句话说,编码后的条形码可以以不同的顺序写入。
]d20105000456013482172012001000001/:210000000001 - 注意:无 /:
在 21 组之后签名,因为它已停产
]d2172012001000001/:210000000001/:0105000456013482 - 注意:均为 10 21组有/.
符号表示我们必须提取直到该符号
]d21000001/:210000000001/:010500045601348217201200 - 前两个是可变长度,接下来的两个是固定长度。
我不是正则表达式方面的专家,到目前为止我只尝试使用一些简单的模式,例如 (01)(\d*)(21)(\d*)(10)(\d*)(17 )(\d*)$
在给定的示例中不起作用,因为它会查找 10 个类似于前 2 个字符的字符。另外,当我知道必须提取字符串的索引时,使用 substring(x, x)
方法仅适用于固定长度字符串的情况。
P.S - 感谢 JS 和 jQuery 的帮助。
最佳答案
虽然您可以尝试创建一个非常复杂的正则表达式来执行此操作,但分步解析字符串会更具可读性和可维护性。
基本步骤是:
- 删除解码方法字符 (]d2)。
- 拆分第 1 步结果中的前两个字符。
- 用它来选择提取数据的方法
- 从字符串中删除并保存该数据,重复执行步骤 2,直到耗尽字符串。
现在,既然您有了人工智能/数据结构的表格,您就可以使用多种方法来提取不同形式的数据
例如,由于 AI: 01, 11, 15, 17 都是固定长度,因此您可以使用字符串的切片方法和长度
str.slice(0,14); //for 01
str.slice(0,6); //for 11 15 17
虽然像 AI 21 这样的变量会是这样的
var fnc1 = "/:";
var fnc1Index = str.indexOf(fnc1);
str.slice(0,fnc1Index);
演示
var dataNames = {
'01': 'GTIN',
'10': 'batchNumber',
'11': 'prodDate',
'15': 'bestDate',
'17': 'expireDate',
'21': 'serialNumber'
};
var input = document.querySelector("input");
document.querySelector("button").addEventListener("click",function(){
var str = input.value;
console.log( parseGS1(str) );
});
function parseGS1(str) {
var fnc1 = "/:";
var data = {};
//remove ]d2
str = str.slice(3);
while (str.length) {
//get the AI identifier: 01,10,11 etc
let aiIdent = str.slice(0, 2);
//get the name we want to use for the data object
let dataName = dataNames[aiIdent];
//update the string
str = str.slice(2);
switch (aiIdent) {
case "01":
data[dataName] = str.slice(0, 14);
str = str.slice(14);
break;
case "10":
case "21":
let fnc1Index = str.indexOf(fnc1);
//eol or fnc1 cases
if(fnc1Index==-1){
data[dataName] = str.slice(0);
str = "";
} else {
data[dataName] = str.slice(0, fnc1Index);
str = str.slice(fnc1Index + 2);
}
break;
case "11":
case "15":
case "17":
data[dataName] = str.slice(0, 6);
str = str.slice(6);
break;
default:
console.log("unexpected ident encountered:",aiIndent);
return false;
break;
}
}
return data;
}
<input><button>Parse</button>
关于javascript - 根据分隔符从字符串中提取子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45918849/