javascript - 根据分隔符从字符串中提取子字符串

标签 javascript jquery regex string substring

我正在尝试从编码的二维条形码中提取数据。提取部分工作正常,我可以在文本输入中获取值。

例如,解码后的字符串是

]d20105000456013482172012001000001/:210000000001

基于以下规则(无法获得正确的表格 Markdown ,因此附上图片),我尝试从上述字符串中提取子字符串。

enter image description here

我要提取的子字符串:

05000456013482(位于分隔符01之后)

201200(位于分隔符 17 之后)

00001(位于分隔符 10 之后)

0000000001(位于分隔符 21 之后)

P.S -> 原始字符串(]d2)中的前 3 个字符始终相同,因为它只是简单地表示解码方法。

现在有一些怪癖:

1) 分隔符10之后的字母数量不固定。因此,在上面给出的示例中,即使它是 00001,它也可能是 001。同样,分隔符21之后的字母数量也不固定,并且可以具有不同的长度。

对于不同长度的分隔符,我添加了一个常量 /: 来确定扫描手持设备后编码何时结束。

现在,我在分隔符 10 之后查找 /: 并提取字符串,直到它到达 /: 或 EOL,找到分隔符 21 并删除该字符串,直到它出现为止点击 /: 或 EOL

2) 分隔符0117之后的字母数量始终是固定的(分别为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 的帮助。

最佳答案

虽然您可以尝试创建一个非常复杂的正则表达式来执行此操作,但分步解析字符串会更具可读性和可维护性。

基本步骤是:

  1. 删除解码方法字符 (]d2)。
  2. 拆分第 1 步结果中的前两个字符。
  3. 用它来选择提取数据的方法
  4. 从字符串中删除并保存该数据,重复执行步骤 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/

相关文章:

javascript - Firefox 中的跨站点 XmlHttpRequest?

javascript - 为什么我无法在 Node REPL 中打开严格检查?

javascript - 如何选择焦点文本区域中的所有文本(在 Safari 中)

javascript - 对正则表达式代码不起作用感到困惑

php - 是否有一个 PHP 函数可以在应用正则表达式模式之前对其进行转义?

javascript - 当我后退时浏览器不执行 JavaScript

javascript - Chrome 10.0.612 开发 Websocket 问题?

javascript - 更改上一页和下一页以进行分页,具有过滤功能

javascript - 如何使用 jQuery 通过 ajax 调用 php 类方法但不需要任何 php 处理程序文件

Python 正则表达式 [\d+]