code: def _search_by_normalizer(
      self,
      doc: Doc,
      normalizer: Callable[[Token], str],
      ignore_space: bool,
  ) -> Iterable[Tuple[int, int]]:
      text = ""
      token_spans: List[Tuple[int, int]] = []
      left = 0
      for token in doc:
          token_text = normalizer(token)
          text += token_text
          right = left + len(token_text)
          if not ignore_space:
              text += token.whitespace_
          token_spans.append((left, right))
          if ignore_space:
              left = right
          else:
              left = right + len(token.whitespace_)
      matches = self.get_char_spans(text)
      return self._get_spans_from_matches(matches, token_spans)
  
file_path: camphr/packages/camphr_pattern_search/camphr_pattern_search/__init__.py
imports: import itertools
  from typing import Callable, Iterable, Iterator, List, Optional, Tuple
  import ahocorasick
  from spacy.tokens.token import Token
  import textspan
  from spacy.tokens import Doc, Span
label_desc: Use image node_id 5 for calling the PatternSearcher obj's underlying member method code with example usage: obj._search_by_normalizer(doc, normalizer, ignore_space) and returns: self