docs: def char_groups(self, t, i):
          """Handle character groups."""
  
          current = []
          pos = i.index - 1
          found = False
          escaped = False
          first = None
          found_property = False
          self.found_property = False
          self.found_named_unicode = False
  
          try:
              while True:
                  # Prevent POSIX/Unicode class from being part of a range.
                  if self.found_property and t == '-':
                      current.append(_re.escape(t))
                      pos += 1
                      t = next(i)
                      self.found_property = False
                      continue
                  else:
                      self.found_property = False
  
                  if not escaped and t == "\\":
                      escaped = True
                  elif escaped:
                      escaped = False
                      idx = len(current) - 1
                      current.extend(self.reference(t, i, True))
                      if self.found_property:
                          # Prevent Unicode class from being part of a range.
                          if idx >= 0 and current[idx] == '-':
                              current[idx] = _re.escape('-')
                          found_property = True
                  elif t == "[" and not found:
                      found = True
                      first = pos
                      current.append(t)
                  elif t == "[":
                      posix = self.get_posix(i)
                      if posix:
                          # Prevent POSIX class from being part of a range.
                          if current[-1] == '-':
                              current[-1] = _re.escape('-')
                          current.extend(self.posix_props(posix, in_group=True))
                          found_property = True
                          pos = i.index - 2
                      else:
                          current.append(t)
                  elif t == "^" and found and (pos == first + 1):
                      first = pos
                      current.append(t)
                  elif t == "]" and found and (pos != first + 1):
                      found = False
                      current.append(t)
                      break
                  else:
                      current.append(t)
                  pos += 1
                  t = next(i)
          except StopIteration:
              pass
  
          if escaped:
              current.append(t)
  
          # Handle properties that return an empty string.
          # This will occur when a property's values exceed
          # either the Unicode char limit on a narrow system,
          # or the ASCII limit in a byte string pattern.
          if found_property or self.found_named_unicode:
              value = "".join(current)
              if value == '[]':
                  # We specified some properties, but they are all
                  # out of reach.  Therefore we can match nothing.
                  current = ['[^%s]' % ('\x00-\xff' if self.is_bytes else _uniprops.UNICODE_RANGE)]
              elif value == '[^]':
                  current = ['[%s]' % ('\x00-\xff' if self.is_bytes else _uniprops.UNICODE_RANGE)]
              else:
                  current = [value]
  
          return current