Parsing parameters with quotes

John Machin sjmachin at lexicon.net
Fri Mar 14 18:02:32 EST 2003


"Giovanni Bajo" <noway at sorry.com> wrote in message news:<Ywaca.11032$Lr4.323544 at twister2.libero.it>...
> My input is:
> 'foo "this is one" and this not':
> and I want to output:
> ["foo", "this is one", "and", "this", "not"]
> 
> Basically, a string.split() but must take into account quotes used to group
> as a single word (no escaping is supported within quotes). Now, is there
> already something in the python library to do this? My code is a bit longer
> than I would have expected:
> Is there any faster way? getopt() does not seem to do this (it's done
> beforehand by whoever fills sys.argv[])

See the following code. Version 2 reproduces the results of (your)
Version 1. Should be faster, but I haven't tested this as I was more
concerned with correctness. I would expect that any argument
surrounded by "" should survive with its contents unmangled. In the
worst case an empty arg "" doesn't even survive. Version 3 below gives
the serendipitous outcome of simpler code plus less disturbing (to me
anyway) results.

Hope this helps,
John

8<---
def SplitParms1(s):
    s = s.split('"')
    L = []
    for i,t in zip(range(0,len(s)), s):
        if t:
            if i%2 == 1:
                L.append(t.strip())
            else:
                L.extend(t.split())
    return L

def SplitParms2(s):
    L = []
    Lappend = L.append
    Lextend = L.extend
    odd = 0
    for t in s.split('"'):
        if t:
            if odd:
                Lappend(t.strip())
            else:
                Lextend(t.split())
        odd = not odd
    return L

def SplitParms3(s):
    L = []
    Lappend = L.append
    Lextend = L.extend
    odd = 0
    for t in s.split('"'):
        if odd:
            Lappend(t)
        else:
            Lextend(t.split())
        odd = not odd
    return L

tests = [
   ['foo "bar zot" ugh', ['foo', 'bar zot', 'ugh']],
   ['',                  []                       ],
   ['one',               ['one']                  ],
   ['"qone"',            ['qone']                 ],
   ['""',                ['']                     ],
   ['arg1 "" "3rd arg"', ['arg1', '', '3rd arg']  ],
   ['"   "',             ['   ']                  ],
   [' x ',               ['x']                    ],
   ['  x  y  ',          ['x', 'y']               ],
   ['" x "',             [' x ']                  ],
   ['x y z "bar zot""   " a', ['x', 'y', 'z', 'bar zot', '   ', 'a']],
]

funcs = [
   SplitParms1,
   SplitParms2,
   SplitParms3,
]
   
if __name__ == "__main__":
   for test_arg, expected in tests:
      for func in funcs:
         actual = func(test_arg)
         if actual == expected:
            flag = "   "
         else:
            flag = "***"
         print "%s %s(%s) -> %s; expected %s" % \
            (flag, func.__name__, repr(test_arg), repr(actual),
repr(expected))
8<---




More information about the Python-list mailing list