Advertisement
DevPlayer

multireplace.py

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