@@ -299,6 +299,61 @@ def splitname(name, strict_mode=True):
299299 return parts
300300
301301
302+ def find_matching (
303+ text : str ,
304+ opening : str ,
305+ closing : str ,
306+ ignore_escaped : bool = True ,
307+ ) -> dict :
308+ r"""
309+ Find matching 'brackets'.
310+
311+ :param text: The string to consider.
312+ :param opening: The opening bracket (e.g. "(", "[", "{").
313+ :param closing: The closing bracket (e.g. ")", "]", "}").
314+ :param ignore_escaped: Ignore escaped bracket (e.g. "\(", "\[", "\{", "\)", "\]", "\}").
315+ :return: Dictionary with ``{index_opening: index_closing}``
316+ """
317+
318+ a = []
319+ b = []
320+
321+ if ignore_escaped :
322+ opening = r"(?<!\\)" + opening
323+ closing = r"(?<!\\)" + closing
324+
325+ for i in re .finditer (opening , text ):
326+ a .append (i .span ()[0 ])
327+
328+ for i in re .finditer (closing , text ):
329+ b .append (- 1 * i .span ()[0 ])
330+
331+ if len (a ) == 0 and len (b ) == 0 :
332+ return {}
333+
334+ if len (a ) != len (b ):
335+ raise IndexError (f"Unmatching { opening } ...{ closing } found" )
336+
337+ brackets = sorted (a + b , key = lambda i : abs (i ))
338+
339+ ret = {}
340+ stack = []
341+
342+ for i in brackets :
343+ if i >= 0 :
344+ stack .append (i )
345+ else :
346+ if len (stack ) == 0 :
347+ raise IndexError (f"No closing { closing } at: { i :d} " )
348+ j = stack .pop ()
349+ ret [j ] = - 1 * i
350+
351+ if len (stack ) > 0 :
352+ raise IndexError (f"No opening { opening } at { stack .pop ():d} " )
353+
354+ return ret
355+
356+
302357def getnames (names ):
303358 """Convert people names as surname, firstnames
304359 or surname, initials.
@@ -322,7 +377,29 @@ def getnames(names):
322377 last = namesplit [0 ].strip ()
323378 firsts = [i .strip () for i in namesplit [1 ].split ()]
324379 else :
325- namesplit = namestring .split ()
380+ if "{" in namestring and "}" in namestring :
381+ try :
382+ brackets = find_matching (namestring , "{" , "}" )
383+ except IndexError :
384+ tidynames .append (namestring )
385+ continue
386+ namesplit = []
387+ start = 0
388+ i = 0
389+ while True :
390+ if i in brackets :
391+ i = brackets [i ]
392+ else :
393+ i += 1
394+ if i >= len (namestring ):
395+ break
396+ if namestring [i ] == " " :
397+ namesplit .append (namestring [start :i ])
398+ start = i + 1
399+ elif i == len (namestring ) - 1 :
400+ namesplit .append (namestring [start :])
401+ else :
402+ namesplit = namestring .split ()
326403 last = namesplit .pop ()
327404 firsts = [i .replace ('.' , '. ' ).strip () for i in namesplit ]
328405 if last in ['jnr' , 'jr' , 'junior' ]:
0 commit comments