"""
Status

M – mandatory,
O – optionalFormat

n – only digits
a – only letters
c – alphanumerical
x – any alphanumerical characters including commas, spaces, etc.
d – amount including a comma as a decimal separator

Example:

2n – up to 2 digits
3!a – always 3 letters
15*65x – up to 15 lines, 65 characters each
"""
import re

FIELDS = {
    "61": '6!n4!n2a1!a15dN3!a16x//16x34x'
}

FIELD_DEF = "(\\/*)((\d+)*)?(\d)(!)?([nacxd])"

TEXT_CLASSES = {
    'n':r'\d',
    'a':r'[A-Z]',
    'c':r'[A-Z\d]',
    'd':r'[\d,]',
    'x':r'[A-Z\d\s,]',
}

def get_regex_parts_from_spec(spec):
    parts = re.findall(FIELD_DEF, spec)
    for part in parts:
        slashes = part[0]
        length = int(part[3])
        min_length = length if part[4] == '!' else 0
        text_class = TEXT_CLASSES[part[5]]

        yield "%s(%s{%i,%i})" % (re.escape(slashes), text_class, min_length, length)

def get_regex_from_spec(spec):
    return "".join(get_regex_parts_from_spec(spec))


def get_field_regex(field_code):
    spec = FIELDS[field_code]
    return get_regex_from_spec(spec)



if __name__ == '__main__':
    print(get_regex_from_spec("2!n"))
@@ -7,17 +7,17 @@
 atus%0A%0AM 
-%E2%80%93
+-
  mandato
@@ -22,17 +22,17 @@
 tory,%0AO 
-%E2%80%93
+-
  optiona
@@ -42,17 +42,17 @@
 rmat%0A%0An 
-%E2%80%93
+-
  only di
@@ -58,17 +58,17 @@
 igits%0Aa 
-%E2%80%93
+-
  only le
@@ -75,17 +75,17 @@
 tters%0Ac 
-%E2%80%93
+-
  alphanu
@@ -94,17 +94,17 @@
 rical%0Ax 
-%E2%80%93
+-
  any alp
@@ -159,17 +159,17 @@
  etc.%0Ad 
-%E2%80%93
+-
  amount 
@@ -223,17 +223,17 @@
 le:%0A%0A2n 
-%E2%80%93
+-
  up to 2
@@ -244,17 +244,17 @@
 its%0A3!a 
-%E2%80%93
+-
  always 
@@ -274,9 +274,9 @@
 65x 
-%E2%80%93
+-
  up 

tidy up some comments