import re paren = re.compile(r"\([^\(\)]*\)") def whiteout(s,start,end): return s[:start] + (' '*(end-start)) + s[end:] def endparen(s,start): end = None while end == None: span = paren.search(s,start).span() if span[0] == start: end = span[1] else: s = whiteout(s,*span) return end def find_named_groups(regex): start = 0 while start < len(regex)-1: try: start = regex.index('(?P',start) yield start start += 1 except ValueError: break def named_group_split(regex): named_groups = list(find_named_groups(regex)) for index in range(len(named_groups)): s0 = named_groups[index] e0 = endparen(regex,s0) s1 = e0 try: if not e0 == named_groups[index+1]: e1 = named_groups[index+1] else: e1 = s1 except IndexError: s1 = e0 e1 = len(regex)+1 yield [regex[s0:e0],regex[s1:e1]] def wrap(s): if s: return 'r"{}"'.format(s) else: return '' def sep_row(row,lengths,add_sep = 0): ret = '' for col in range(len(row)-1): if row[col+1]: ret += row[col].ljust(lengths[col]+add_sep,' ') else: ret += row[col] return ret + row[-1] def list2dstring(list2d,space=1): col_length = [] for col in range(len(list2d[0])-1): col_length.append( max( map( len,(row[col] for row in list2d) ) ) ) col_length.append(0) ret = [] for row in list2d: ret.append(sep_row(list(map(wrap,row)),col_length,add_sep = 4)) return '\n'.join(ret) def pformat_regex(regex): return '\n'+list2dstring(list(named_group_split(regex)))+'\n' if __name__ == "__main__": from Npp import editor start = editor.getSelectionStart() content = editor.getSelText() prev_content = content content = re.sub(r'^\(?r?[\"\']|[\"\']\)?','',content) result = pformat_regex(content) if prev_content[0] == '(': result = '(' + result if prev_content[-1] == ')': result = result + ')' editor.replaceSel(result) editor.setSelectionStart(start) editor.setSelectionEnd(start + len(result))