4

I'm busy with GS1-128 and want to match scanned barcodes using RegEx. I currently have the following expression:

^(01)(12345678)(\d{5})\d(11|17)(\d{2}[0-1]\d[0-3]\d)(10|21)(\d{1,20})(30)(\d{1,20})

This succesfully matches the barcode (01)12345678123450(11)130500(21)1234567890(30)42, splitting it up into the following groups:

  1. 01 - GTIN
  2. 12345678 - company code (dummy) - 8 digits
  3. 12345 - partcode (dummy) - 5 digits
  4. 11 or 17 - Production date/expiry date
  5. 130500 - date - 6 digits
  6. 10 or 21 - batch/serial number
  7. 1234567890 - 1 to 20 characters
  8. 30 - count of items (optional)
  9. 42 - 1 to 8 characters (optional)

Now, I sometimes have a barcode that doesn't have the count of items AI; 30. I can't seem to figure out how to work this into my regex at all. Whenever I make group 8 & 9 optional, the content of these groups get thrown into group 7 for all barcodes that do contain AI 30.

How do I go about making AI 30 optional while preventing it from being grouped with AI 21/10?

Test cases:

(01)12345678654320(11)120500(21)1234567890 should give the following matches:

  1. 01
  2. 12345678
  3. 65432
  4. 11
  5. 120500
  6. 21
  7. 1234567890
  8. NO MATCH
  9. NO MATCH

(01)12345678124570(17)130700(10)30567(30)50 should give the following matches:

  1. 01
  2. 12345678
  3. 12457
  4. 17
  5. 130700
  6. 10
  7. 30567
  8. 30
  9. 50

(01)12345678888880(11)140200(21)66503042(30)100 should give the following matches:

  1. 01
  2. 12345678
  3. 88888
  4. 11
  5. 140200
  6. 21
  7. 66503042
  8. 30
  9. 100

Note that the parentheses are only to show where the AI begins, the barcode itself omits these.

4

3 回答 3

2

尝试这个:

^(?<gtin>\(01\))(?<comp_code>12345678)(?<part_code>\d{5})0?(?<pd_ed>\((?:11|17)\))(?<date>\d{6})(?<bat_no>\((?:21|10)\))(?<data_req>\d{1,20}?)\b(?<count>(?:\(30\))?)(?<data_opt>(?:\d{1,8})?)$

上述表达式应匹配以下所有项:

(01)12345678654320(11)120500(21)1234567890
(01)12345678124570(17)130700(10)30567(30)50
(01)12345678888880(11)140200(21)66503042(30)100

解释:

<!--
^(?<gtin>\(01\))(?<comp_code>12345678)(?<part_code>\d{5})0?(?<pd_ed>\((?:11|17)\))(?<date>\d{6})(?<bat_no>\((?:21|10)\))(?<data_req>\d{1,20}?)\b(?<count>(?:\(30\))?)(?<data_opt>(?:\d{1,8})?)$

Assert position at the beginning of the string «^»
Match the regular expression below and capture its match into backreference with name “gtin” «(?<gtin>\(01\))»
   Match the character “(” literally «\(»
   Match the characters “01” literally «01»
   Match the character “)” literally «\)»
Match the regular expression below and capture its match into backreference with name “comp_code” «(?<comp_code>12345678)»
   Match the characters “12345678” literally «12345678»
Match the regular expression below and capture its match into backreference with name “part_code” «(?<part_code>\d{5})»
   Match a single digit 0..9 «\d{5}»
      Exactly 5 times «{5}»
Match the character “0” literally «0?»
   Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match the regular expression below and capture its match into backreference with name “pd_ed” «(?<pd_ed>\((?:11|17)\))»
   Match the character “(” literally «\(»
   Match the regular expression below «(?:11|17)»
      Match either the regular expression below (attempting the next alternative only if this one fails) «11»
         Match the characters “11” literally «11»
      Or match regular expression number 2 below (the entire group fails if this one fails to match) «17»
         Match the characters “17” literally «17»
   Match the character “)” literally «\)»
Match the regular expression below and capture its match into backreference with name “date” «(?<date>\d{6})»
   Match a single digit 0..9 «\d{6}»
      Exactly 6 times «{6}»
Match the regular expression below and capture its match into backreference with name “bat_no” «(?<bat_no>\((?:21|10)\))»
   Match the character “(” literally «\(»
   Match the regular expression below «(?:21|10)»
      Match either the regular expression below (attempting the next alternative only if this one fails) «21»
         Match the characters “21” literally «21»
      Or match regular expression number 2 below (the entire group fails if this one fails to match) «10»
         Match the characters “10” literally «10»
   Match the character “)” literally «\)»
Match the regular expression below and capture its match into backreference with name “data_req” «(?<data_req>\d{1,20}?)»
   Match a single digit 0..9 «\d{1,20}?»
      Between one and 20 times, as few times as possible, expanding as needed (lazy) «{1,20}?»
Assert position at a word boundary «\b»
Match the regular expression below and capture its match into backreference with name “count” «(?<count>(?:\(30\))?)»
   Match the regular expression below «(?:\(30\))?»
      Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
      Match the character “(” literally «\(»
      Match the characters “30” literally «30»
      Match the character “)” literally «\)»
Match the regular expression below and capture its match into backreference with name “data_opt” «(?<data_opt>(?:\d{1,8})?)»
   Match the regular expression below «(?:\d{1,8})?»
      Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
      Match a single digit 0..9 «\d{1,8}»
         Between one and 8 times, as many times as possible, giving back as needed (greedy) «{1,8}»
Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
-->

编辑

省略转义括号:

^(?<gtin>01)(?<comp_code>12345678)(?<part_code>\d{5})0?(?<pd_ed>(?:11|17))(?<date>\d{6})(?<bat_no>(?:21|10))(?<data_req>\d{1,20}?)\b(?<count>(?:30)?)(?<data_opt>(?:\d{1,8})?)$
于 2013-07-01T11:14:40.707 回答
1

可变长度 AI 应以 FNC1 字符终止。如果存在,您应该使用它来查找\d{1,20}.

如果它不存在,我会找出它被剥离的位置并防止它被剥离。

于 2013-08-07T14:48:37.113 回答
0

试试这个,这会给你匹配所有段的组。(3302)103300(10)L20060831A117 , (02)04008577004106(15)081231(37)000025

\(\d{1,3}[0-9,a-z,A-Z]{1}?\)[\d,a-z,A-Z]{1,70}

之后你可以应用这个正则表达式吗

\((.*?)\)

在每个段上找出哪个 AI 有代码部分,然后您可以验证代码部分是否满足他的 AI 的条件。

于 2020-02-25T08:51:34.773 回答