RegEx Example: IMEI or ICCID Requiring Leading or Trailing Keywords

RegEx (using the pipe '|' as an OR between conditions):

pData->data =
    _T("(?i)"
       "(?:\\bICCID\\b[^\\r\\n]*?(?<!\\d)89\\d{17,18}(?!\\d)"
       "|(?<!\\d)89\\d{17,18}(?!\\d)[^\\r\\n]*?\\bICCID\\b"
       "|\\b(?:IMEA|IMEI|SIM)\\b[^\\r\\n]*?(?<!\\d)\\d{15}(?:\\d{2})?(?!\\d)"
       "|(?<!\\d)\\d{15}(?:\\d{2})?(?!\\d)[^\\r\\n]*?\\b(?:IMEA|IMEI|SIM)\\b)");

In simple terms:

  • (?i) – Make the match case-insensitive
    • iccid, ICCID, Imei, etc. all match
  • The whole code block is a big “OR” group with four patterns:
    1. ICCID label on the same line before an ICCID-shaped number
    2. ICCID-shaped number before the ICCID label
    3. IMEA, IMEI, or SIM label on the same line before a 15- or 17-digit number
    4. 15- or 17-digit number before the IMEA/IMEI/SIM label
  • For ICCID patterns:
    • The number must start with 89 and then have 17 or 18 more digits19–20 digits total
    • (?<!\\d) and (?!\\d) around the number means it cannot be part of a longer digit string
    • [^\r\n]*? between the label and number means “any characters on the same line” (spaces, punctuation, etc.), but do not cross a newline.
  • For IMEA / IMEI / SIM patterns:
    • The label is one of IMEA, IMEI, or SIM as a whole word.
    • The number is 15 digits, optionally followed by 2 more digits15 or 17 digits total.
    • Again, (?<!\\d) / (?!\\d) ensure it’s not embedded inside a longer run of digits.
    • [^\r\n]*? allows any same-line characters between label and number.
  • Net effect:
    This regex finds ICCID, IMEI, IMEA, and SIM style identifiers only when:
    • They are on the same line as the appropriate label,
    • The numeric portion has the correct length/shape, and
    • The number isn’t just a slice of a larger digit blob.


Was this article helpful?