title: Python String Templating with Case Sensitivity
body: <p>This is a naming script that i use to name nodes in Autodesk Maya. This particular script however doesnt use anything maya specific.</p>
  
  <p>I had asked a while ago how I would go about doing something like this, where a variable convention could be used, and templating came up. </p>
  
  <p>So if i had a convention like this: </p>
  
  <pre><code>'${prefix}_${name}_${side}_${type}'
  </code></pre>
  
  <p>I could pass these arguments:</p>
  
  <pre><code>bind_thigh_left_joint
  </code></pre>
  
  <p>And then run them through an abbreviation dictionary (as well as a user abbreviation dictionary), check it with relevant nodes in scene file to make sure there are no duplicates, and end up with this: <code>bn_thigh_L_jnt</code></p>
  
  <p>However I wanted it so that if one of the keys has a first uppercase letter, it would make the substitute uppercase. </p>
  
  <p>For example if <code>{$prefix}</code> was instead <code>{$Prefix}</code> thigh would become Thigh, or if <code>{$prefix}</code> was <code>{$PREFIX}</code> thigh would become THIGH. However if it was <code>{$PREfix}</code> thigh would still only be Thigh.</p>
  
  <p>I can do this easily enough except that I have no way to detect the individual cases of the keys. For example, if the string is <code>'${Prefix}_${name}_${SIDE}_${type}'</code> How would I find what case prefix is, and if i knew that, how would i use that with this template?</p>
  
  <p>Note this code isnt the exact code i have, I have ommitted a lot of other stuff that was more maya specific, this just deals with the substituting itself.</p>
  
  <pre><code>from string import Template
  import collections
  
  def convert(prefix, name, side, obj_type):
      user_conv = '${Prefix}_${name}_${SIDE}_${type}'
      # Assigns keys to strings to be used by the user dictionary.
      subs = {'prefix': prefix, 'name': name, 'side': side, 'type': obj_type}
  
      # Converts all of user convention to lowercase, and substitutes the names from subs.
      new_name = Template(user_conv.lower())
      new_name = new_name.safe_substitute(**subs)
      # Strips leading and trailing underscores, and replaces double underscores with a single
      new_name = new_name.strip('_')
      new_name = new_name.replace('__', '_')
  
      return new_name
  
  print convert('bind', 'thigh', 'left', 'joint')
  &gt;&gt; bind_thigh_left_joint
  </code></pre>
  
  <p>Edit:
  Also would like to strip multiple underscores</p>
  
  <p>So if I had something like:</p>
  
  <pre><code>'${prefix}___${name}__${side}_____${type}'
  </code></pre>
  
  <p>I would want it to come out </p>
  
  <pre><code>&gt;&gt; bind_thigh_left_joint
  </code></pre>
  
  <p>not</p>
  
  <pre><code>&gt;&gt; bind___thigh__left____joint
  </code></pre>
  
  <p>Also the last thing, I figured since a user would be inputting this, it would be more convenient not to be adding brackets and dollar signs. Would it be possible to do something like this?</p>
  
  <pre><code>import re
  user_conv = 'PREFIX_name_Side_TYPE01'
  # do all filtering, removing of underscores and special characters
  templates = ['prefix', 'name', 'side', 'type']
  for template in templates:
      if template in user_conv.lower():
          # add bracket and dollar sign around match
  
  &gt;&gt; '${PREFIX}_{name}_{Side}_${TYPE}01'
  </code></pre>