docs: def identify_report_numbers(line, kb_reports):
      """Attempt to identify all preprint report numbers in a reference
         line.
         Report numbers will be identified, their information (location
         in line, length in line, and standardised replacement version)
         will be recorded, and they will be replaced in the working-line
         by underscores.
         @param line: (string) - the working reference line.
         @param preprint_repnum_search_kb: (dictionary) - contains the
          regexp patterns used to identify preprint report numbers.
         @param preprint_repnum_standardised_categs: (dictionary) -
          contains the standardised 'category' of a given preprint report
          number.
         @return: (tuple) - 3 elements:
             * a dictionary containing the lengths in the line of the
               matched preprint report numbers, keyed by the index at
               which each match was found in the line.
             * a dictionary containing the replacement strings (standardised
               versions) of preprint report numbers that were matched in
               the line.
             * a string, that is the new version of the working reference
               line, in which any matched preprint report numbers have been
               replaced by underscores.
          Returned tuple is therefore in the following order:
              (matched-reportnum-lengths, matched-reportnum-replacements,
               working-line)
      """
      def _by_len(a, b):
          """Comparison function used to sort a list by the length of the
             strings in each element of the list.
          """
          if len(a[1]) < len(b[1]):
              return 1
          elif len(a[1]) == len(b[1]):
              return 0
          else:
              return -1
  
      repnum_matches_matchlen = {}  # info about lengths of report numbers
      # matched at given locations in line
      repnum_matches_repl_str = {}  # standardised report numbers matched
      # at given locations in line
  
      repnum_search_kb, repnum_standardised_categs = kb_reports
      repnum_categs = repnum_standardised_categs.keys()
      repnum_categs.sort(_by_len)
  
      # Handle CERN/LHCC/98-013
      line = line.replace('/', ' ')
  
      # try to match preprint report numbers in the line:
      for categ in repnum_categs:
          # search for all instances of the current report
          # numbering style in the line:
          repnum_matches_iter = repnum_search_kb[categ].finditer(line)
  
          # for each matched report number of this style:
          for repnum_match in repnum_matches_iter:
              # Get the matched text for the numeration part of the
              # preprint report number:
              numeration_match = repnum_match.group('numn')
              # clean/standardise this numeration text:
              numeration_match = numeration_match.replace(" ", "-")
              numeration_match = re_multiple_hyphens.sub("-", numeration_match)
              numeration_match = numeration_match.replace("/-", "/")
              numeration_match = numeration_match.replace("-/", "/")
              numeration_match = numeration_match.replace("-/-", "/")
  
              # replace the found preprint report number in the
              # string with underscores
              # (this will replace chars in the lower-cased line):
              line = line[0:repnum_match.start(1)] \
                  + "_" * len(repnum_match.group(1)) + line[repnum_match.end(1):]
  
              # record the information about the matched preprint report number:
              # total length in the line of the matched preprint report number:
              repnum_matches_matchlen[repnum_match.start(1)] = \
                  len(repnum_match.group(1))
              # standardised replacement for the matched preprint report number:
              repnum_matches_repl_str[repnum_match.start(1)] = \
                  repnum_standardised_categs[categ] \
                  + numeration_match
  
      # return recorded information about matched report numbers, along with
      # the newly changed working line:
      return repnum_matches_matchlen, repnum_matches_repl_str, line