DevPlayer

multireplace.py

Nov 5th, 2011
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.17 KB | None | 0 0
  1.  
  2. # 2011-Nov-04
  3.  
  4. # This is my first text parsing program.
  5.  
  6. # This is my first implementation of a simple
  7. # string parser and transform (I call recompile)
  8. # of a given string into a new string based on
  9. # a list of given (valid) keyword strings.
  10.  
  11. # From within Python instead of a MS-DOS script
  12. # I wanted to compile/transform/convert
  13. # the value of the MS-DOS PROMPT envar variable,
  14. # usaually PROMPT = "$P$G",
  15. # to what would be displayed by MS-DOS.
  16.  
  17. # But it can be used for a lot more.
  18.  
  19. # globals()['__doc__'] =
  20. '''Parse (partition) a string in to a list of valid and
  21. invalid words (strings), while retaining the same order of
  22. both.
  23.  
  24. Valid words are supplied by the caller in a list of strings.
  25.  
  26. An invalid word is anything between valid words, before any
  27. valid words or after any valid words.
  28.  
  29. Then recompile the string with values from a dict whose keys
  30. are the valid words yet keep the invalid words in place.
  31.  
  32. Example:
  33.    "invalid00;Valid00Invalid02Valid01I.n'valid03"
  34. where Valid00 remaps to " HELLO " and "Valid01" remaps to " WORLD! "
  35. you should get:
  36.    "invalid00; HELLO Invalid02 WORLD! I.n'valid03"
  37. '''
  38.  
  39.  
  40. # These are the main functions
  41. def getValidWord(keywords, string):
  42.     for word in keywords:
  43.         if string.startswith(word):
  44.             return word
  45.     return ''
  46.  
  47. def getInvalidWord(keywords, string):
  48.     lstring = len(string)
  49.     for i in range(lstring):
  50.         for word in keywords:
  51.             if string[i:].startswith(word):
  52.                 return string[0:i]
  53.     return string
  54.  
  55.  
  56. def parse(string, keywords):
  57.     # copy original string as this function is destructive to string
  58.     s = string[:]
  59.     words = []
  60.     word = ''
  61.     interations = 0
  62.     while len(s) > 0:
  63.  
  64.         # try and get a keyword
  65.         word = getValidWord(keywords, s)
  66.         if word and s.startswith(word):
  67.             words.append(word)
  68.             s = s.replace(word, '', 1)
  69.  
  70.         # try and get whatever is not a keyword
  71.         word = getInvalidWord(keywords, s)
  72.         if word and s.startswith(word):
  73.             words.append(word)
  74.             s = s.replace(word, '', 1)
  75.  
  76.         interations += 1
  77.     return words
  78.  
  79. # similar to map() i guess
  80. def recompile(string, mapping):
  81.     keywords = mapping.keys()
  82.     words = parse(string, keywords)
  83.  
  84.     new_words = []
  85.     for word in words:
  86.         if word in keywords:
  87.             if callable(mapping[word]):
  88.                 ret_word = mapping[word]()
  89.                 new_words.append( str( ret_word ) )
  90.             else:
  91.                 new_words.append( str( mapping[word] ) )
  92.         else:
  93.             new_words.append( str( word ) )
  94.  
  95.     new_string = ''.join(new_words)
  96.  
  97.     return new_string
  98.  
  99.  
  100. # These functions support DOS prompt conversion/tranform/recompile
  101. def getcwdrive():
  102.     import os
  103.     return os.path.splitdrive(os.getcwd())[0]
  104.  
  105. def msdosdate():
  106.     import datetime
  107.     now = datetime.datetime.today()
  108.     dosformat = now.strftime('%a %m/%d/%Y')
  109.     return dosformat
  110.  
  111. def msdostime():
  112.     import datetime
  113.     now = datetime.datetime.today()
  114.     dosformat = now.strftime('%X.00')
  115.     return dosformat
  116.  
  117. def msdosprompt():
  118.     '''Processes the DOS "PROMPT" environment variable
  119.    and returns it's string.'''
  120.     import os
  121.     prompt = os.getenv('prompt', '$P$G')
  122.     prompt_mapper = msdosprompt_mapper()
  123.     transformed = recompile(prompt, prompt_mapper)
  124.     return transformed
  125.    
  126.  
  127. def msdosprompt_mapper():
  128.     import os
  129.     import sys
  130.     import collections
  131.     special_codes = collections.OrderedDict()
  132.     sc = special_codes
  133.     sc['$A'] = '&'
  134.     sc['$B'] = '|'
  135.     sc['$C'] = '('
  136.     sc['$D'] = msdosdate
  137.     sc['$E'] = chr(27)
  138.     sc['$F'] = ')'
  139.     sc['$G'] = '>'
  140.     sc['$H'] = '\b'
  141.     sc['$I'] = '$I'
  142.     sc['$J'] = '$J'
  143.     sc['$K'] = '$K'
  144.     sc['$L'] = '>'
  145.     sc['$M'] = '$M'
  146.     sc['$N'] = getcwdrive
  147.     sc['$O'] = '$O'
  148.     sc['$P'] = os.getcwd
  149.     sc['$Q'] = '='
  150.     sc['$R'] = '$R'
  151.     sc['$S'] = ' '
  152.     sc['$T'] = msdostime
  153.     sc['$U'] = '$U'
  154.     sc['$V'] = sys.version
  155.     sc['$W'] = '$W'
  156.     sc['$X'] = '$X'
  157.     sc['$Y'] = '$Y'
  158.     sc['$Z'] = '$Z'
  159.     sc['$_'] = '\r\n'
  160.     sc['$$'] = '$'
  161.     sc['$+'] = '$+'
  162.     sc['$M'] = ''
  163.     return special_codes
  164.  
  165. def mdosprompthelp():
  166.     # Warning: copy directly from Microsoft Windows XP without permission.
  167.     print('''
  168. Changes the cmd.exe command prompt.
  169.  
  170. PROMPT [text]
  171.  
  172.  text    Specifies a new command prompt.
  173.  
  174. Prompt can be made up of normal characters and the following special codes:
  175.  
  176.  $A   & (Ampersand)
  177.  $B   | (pipe)
  178.  $C   ( (Left parenthesis)
  179.  $D   Current date
  180.  $E   Escape code (ASCII code 27)
  181.  $F   ) (Right parenthesis)
  182.  $G   > (greater-than sign)
  183.  $H   Backspace (erases previous character)
  184.  $L   < (less-than sign)
  185.  $N   Current drive
  186.  $P   Current drive and path
  187.  $Q   = (equal sign)
  188.  $S     (space)
  189.  $T   Current time
  190.  $V   Windows XP version number
  191.  $_   Carriage return and linefeed
  192.  $$   $ (dollar sign)
  193.  
  194. If Command Extensions are enabled the PROMPT command supports
  195. the following additional formatting characters:
  196.  
  197.  $+   zero or more plus sign (+) characters depending upon the
  198.       depth of the PUSHD directory stack, one character for each
  199.       level pushed.
  200.  
  201.  $M   Displays the remote name associated with the current drive
  202.       letter or the empty string if current drive is not a network
  203.       drive.
  204.    ''')
  205.  
  206.  
  207.  
  208. def usage():
  209.     '''Print package usage.'''
  210.     print( globals()['__doc__'] )
  211.  
  212.  
  213. if __name__ == '__main__':
  214.     import sys
  215.     # ///////////////////////////////////
  216.     def is_argv_help():
  217.         '''See if user supplied a command line help argument,
  218.        if so print usage and exit.'''
  219.         import sys
  220.         help = ['-h', '--h', '-help', '--help', '/h', '/help']
  221.         for arg in sys.argv[1:]:
  222.             if arg.lower() in help:
  223.                 usage()
  224.                 sys.exit(0)
  225.  
  226.     is_argv_help()
  227.     # ///////////////////////////////////
  228.     # ///////////////////////////////////
  229.  
  230.     # ///////////////////////////////////
  231.     def test_parse(string, keywords):
  232.         '''copy of parse() with interactive prompt and debug messages'''
  233.         # copy original string as this function is destructive to string
  234.         s = string[:]
  235.         words = []
  236.         word = ''
  237.         interations = 0
  238.         while raw_input('%d: >'% interations) <> 'q' and len(s) > 0:
  239.             print s
  240.             word = getValidWord(keywords, s)
  241.             print '  valid return: ', repr(word)
  242.             if word and s.startswith(word):
  243.                 words.append(word)
  244.                 s = string.replace(word, '', 1)
  245.  
  246.             word = getInvalidWord(keywords, s)
  247.             print 'invalid return: ', repr(word)
  248.             if word and s.startswith(word):
  249.                 words.append(word)
  250.                 s = s.replace(word, '', 1)
  251.  
  252.             print 'words:', words
  253.             print
  254.             interations += 1
  255.         return words
  256.  
  257.     # ///////////////////////////////////
  258.     if 'test1' in sys.argv:
  259.         def test1(test_string, test_keywords):
  260.             print('')
  261.             print('Parse: %r' % test_string)
  262.             print('')
  263.             print(' into valid and invalid keywords: %r' % test_keywords)
  264.             words = parse(test_string, test_keywords)
  265.             print('')
  266.             print('String was broken down (parsed) into:')
  267.             print('')
  268.             print('  %r' % words)
  269.             print('')
  270.  
  271.  
  272.     # ///////////////////////////////////
  273.     if 'test2' in sys.argv:
  274.         def test2(test_string, test_mapping):
  275.             print('-'*70)
  276.             print('')
  277.             print('Reformat test string: %r' % test_string)
  278.             print('')
  279.             print(' using mapping: %r' % test_mapping)
  280.             string = recompile(test_string, test_mapping)
  281.             print('')
  282.             print('String was reformatted into:')
  283.             print('')
  284.             print('  %r' % string)
  285.             print(string)
  286.             print('')
  287.  
  288.  
  289.     # ///////////////////////////////////
  290.     # test one
  291.     if 'test1' in sys.argv:
  292.         # pay very close attention to spaces and spelling
  293.         # there's a few twists in this tests
  294.         test_keywords = ['one','two','three ','five','size']
  295.         test_string = 'one potatoe, two tomatoe, three oregano, more,fivesix'
  296.         test1(test_string, test_keywords)
  297.        
  298.  
  299.     # ///////////////////////////////////
  300.     # test two
  301.     if 'test2' in sys.argv:
  302.         special_codes = msdosprompt_mapper()
  303.         prompt = '$D $T$P$G$EmOLLy   $H $H$H$X:$S$N$.$G$G$G'
  304.         test2(prompt, special_codes)
  305.  
  306.  
  307.     # ///////////////////////////////////
  308.     # test three
  309.     if 'test3' in sys.argv:
  310.         import collections
  311.         keywords = collections.OrderedDict()
  312.         keywords['Valid00'] = ' HELLO '
  313.         keywords['Valid01'] = ' WORLD! '
  314.         string = "invalid00;Valid00Invalid02Valid01I.n'valid03"
  315.         print( 'Keywords:' )
  316.         print( '   %r' % keywords.keys() )
  317.         print( 'Original string:')
  318.         print( '   %r' % string )
  319.         print( 'Recompiled/transformed string:' )
  320.         print( '   %r' % recompile(string, keywords) )
  321.  
  322.  
  323.  
  324.  
Advertisement
Add Comment
Please, Sign In to add comment