Hi, I'm writing utilities to handle return values from AppleScript in python and one of the steps is recognizing when a returned value from an AppleScript execution (via popen and osascript) represents a list (in AppleScript) or not. For the most part I think I have the correct matching pattern, but I am hung up on one of the sample strings I was using to test it - AppleScript allows for one level of nested lists (I believe) and I get tripped up with attempting to match lists with nested lists.
My second question is, once I have a pattern matching correctly, I need to convert the AppleScript list into a Python list - I've read a bit about the findall() method of the re module and was wondering if that would work in this instance (there's also split() but I've been having issues with that, probably b/c my pattern matching isn't correct). Thank you! Andrew (source code below) #!/usr/bin/env python # Sample script to test if a string represented an AppleScript List or not import re import os def IsASList(thestr=''): # AppleScript lists are bracked by curly braces with items separate by commas # Each item is an alphanumeric label(?) or a string enclosed by # double quotes or a list itself # e.g. {2, True, "hello"} # # They differ from AppleScript records in that AS records have a key and value: # {name: "Buffy", field: "Slaying", job: true, age: 21} # # Now the question is how to make the distinction? pattern = ''' ^{ # Must start with a curly brace ( \s*? # Group to repeat; clear the whitespace after commas first ( # Start of group of alternating match possibilities ".+?" # Match a string | \d+? # Match a number | true|false # Match 'true' or 'false' label ) # End of group of alternating match possibilities ,?)* # Items are comma-delimited, except for the last item }$ # Must end with a closing curly brace ''' pattern2 = ''' ( \s*? # Group to repeat; clear the whitespace after commas first ( # Start of group of alternating match possibilities ".+?" # Match a string | \d+? # Match a number | true|false # Match 'true' or 'false' label ) # End of group of alternating match possibilities ,?)* # Items are comma-delimited, except for the last item ''' pattern3 = ''' ^{ ( %s | {%s} # Possible to have 1 level of nested lists ,?)* # Items are comma-delimited, except for the last item }$ ''' % (pattern2, pattern2) regex = re.compile(pattern3, re.VERBOSE) result = regex.match(thestr) # print 'Result: ', # try: # print result.groups() # except AttributeError: # pass if result: return True else: return False # main() sample_strs = [ '{}', # Empty list '{a}', # Should not match '{a, b, c}', # Should not match '{"hello"}', '{"hello", "kitty"}', '{true}', '{false}', '{true, false}', '{9}', '{9,10, 11}', '{93214, true, false, "hello", "kitty"}', '{{1, 2, 3}}', # This matches '{{1, 2, "cat"}, 1}', # This matches # These don't match: '{{1,2,3},1,{4,5,6},2}', '{1, {2, 3, 4}, 3}', '{{1, 2, 3}, {4, 5, 6}, 1}', '{1, {1, 2, 3}}', # Should match but doesn't '{93214, true, false, "hello", "kitty", {1, 2, 3}}', # Should match but doesn't '{label: "hello", value: false, num: 2}', # AppleScript dictionary - should not match ] for sample in sample_strs: print 'Is AppleScript List: %s; String: %s' % (str(IsASList(sample)), sample)
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor