import re INTERFACE_NAME_REGEX = r'(^(?P[^\d\.:]+)?)' \ r'((?P\d+)/)?' \ r'((?P\d+)/)?' \ r'((?P\d+)/)?' \ r'((?P\d+)/)?' \ r'((?P\d+))?' \ r'(:(?P\d+))?' \ r'(.(?P\d+)$)?' def naturalize(value, max_length, integer_places=8): """ Take an alphanumeric string and prepend all integers to `integer_places` places to ensure the strings are ordered naturally. For example: site9router21 site10router4 site10router19 becomes: site00000009router00000021 site00000010router00000004 site00000010router00000019 :param value: The value to be naturalized :param max_length: The maximum length of the returned string. Characters beyond this length will be stripped. :param integer_places: The number of places to which each integer will be expanded. (Default: 8) """ if not value: return value output = [] for segment in re.split(r'(\d+)', value): if segment.isdigit(): output.append(segment.rjust(integer_places, '0')) elif segment: output.append(segment) ret = ''.join(output) return ret[:max_length] def naturalize_interface(value, max_length): """ Similar in nature to naturalize(), but takes into account a particular naming format adapted from the old InterfaceManager. :param value: The value to be naturalized :param max_length: The maximum length of the returned string. Characters beyond this length will be stripped. """ output = [] match = re.search(INTERFACE_NAME_REGEX, value) if match is None: return value # First, we order by slot/position, padding each to four digits. If a field is not present, # set it to 9999 to ensure it is ordered last. for part_name in ('slot', 'subslot', 'position', 'subposition'): part = match.group(part_name) if part is not None: output.append(part.rjust(4, '0')) else: output.append('9999') # Append the type, if any. if match.group('type') is not None: output.append(match.group('type')) # Finally, append any remaining fields, left-padding to six digits each. for part_name in ('id', 'channel', 'vc'): part = match.group(part_name) if part is not None: output.append(part.rjust(6, '0')) else: output.append('000000') ret = ''.join(output) return ret[:max_length]