31

Is it possible to use a regex for parsing an argument? For example, I want to accept an argument if only it is a 32 length hex (i.e. matches /[a-f0-9A-F]{32}/)

I tried

p.add_argument('hex', type=str, nargs="[a-f0-9A-F]{32}")

without success

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Kousha
  • 32,871
  • 51
  • 172
  • 296
  • 1
    Alternatively, take a look at [this question](http://stackoverflow.com/questions/14665234/argparse-choices-structure-of-allowed-values). – fenceop Jan 26 '17 at 19:08
  • 1
    `argparse` does use `regex` expressions to count argument strings, but it generates the patterns itself. The allowed `nargs` values like `*+?' have a regex feel, but they aren't used directly. They are actually values of module constants (like `argparse.ZERO_OR_MORE`), and are used in `if else` tests. – hpaulj Jan 26 '17 at 21:08

1 Answers1

61

The type keyword argument can take any callable that accepts a single string argument and returns the converted value. If the callable raises argparse.ArgumentTypeError, TypeError, or ValueError, the exception is caught and a nicely formatted error message is displayed.

import argparse
import re 
from uuid import uuid4

def my_regex_type(arg_value, pat=re.compile(r"^[a-f0-9A-F]{32}$")):
    if not pat.match(arg_value):
        raise argparse.ArgumentTypeError("invalid value")
    return arg_value

parser = argparse.ArgumentParser()
parser.add_argument('hex', type=my_regex_type)

args = parser.parse_args([uuid4().hex])
leesei
  • 6,020
  • 2
  • 29
  • 51
wim
  • 338,267
  • 99
  • 616
  • 750