text: """
  Module containing a preprocessor that removes cells if they match
  one or more regular expression.
  """
  
  # Copyright (c) IPython Development Team.
  # Distributed under the terms of the Modified BSD License.
  
  from traitlets import Set, Unicode
  
  from .base import Preprocessor
  
  
  class TagRemovePreprocessor(Preprocessor):
      """
      Removes inputs, outputs, or cells from a notebook that
      have tags that designate they are to be removed prior to exporting
      the notebook.
  
      remove_cell_tags
          removes cells tagged with these values
  
      remove_all_outputs_tags
          removes entire output areas on cells
          tagged with these values
  
      remove_single_output_tags
          removes individual output objects on
          outputs tagged with these values
  
      remove_input_tags
          removes inputs tagged with these values
      """
  
      remove_cell_tags = Set(
          Unicode(),
          default_value=[],
          help=(
              "Tags indicating which cells are to be removed,"
              "matches tags in ``cell.metadata.tags``."
          ),
      ).tag(config=True)
      remove_all_outputs_tags = Set(
          Unicode(),
          default_value=[],
          help=(
              "Tags indicating cells for which the outputs are to be removed,"
              "matches tags in ``cell.metadata.tags``."
          ),
      ).tag(config=True)
      remove_single_output_tags = Set(
          Unicode(),
          default_value=[],
          help=(
              "Tags indicating which individual outputs are to be removed,"
              "matches output *i* tags in ``cell.outputs[i].metadata.tags``."
          ),
      ).tag(config=True)
      remove_input_tags = Set(
          Unicode(),
          default_value=[],
          help=(
              "Tags indicating cells for which input is to be removed,"
              "matches tags in ``cell.metadata.tags``."
          ),
      ).tag(config=True)
      remove_metadata_fields = Set({"collapsed", "scrolled"}).tag(config=True)
  
      def check_cell_conditions(self, cell, resources, index):
          """
          Checks that a cell has a tag that is to be removed
  
          Returns: Boolean.
          True means cell should *not* be removed.
          """
  
          # Return true if any of the tags in the cell are removable.
          return not self.remove_cell_tags.intersection(cell.get("metadata", {}).get("tags", []))
  
      def preprocess(self, nb, resources):
          """
          Preprocessing to apply to each notebook. See base.py for details.
          """
          # Skip preprocessing if the list of patterns is empty
          if not any(
              [
                  self.remove_cell_tags,
                  self.remove_all_outputs_tags,
                  self.remove_single_output_tags,
                  self.remove_input_tags,
              ]
          ):
              return nb, resources
  
          # Filter out cells that meet the conditions
          nb.cells = [
              self.preprocess_cell(cell, resources, index)[0]
              for index, cell in enumerate(nb.cells)
              if self.check_cell_conditions(cell, resources, index)
          ]
  
          return nb, resources
  
      def preprocess_cell(self, cell, resources, cell_index):
          """
          Apply a transformation on each cell. See base.py for details.
          """
  
          if (
              self.remove_all_outputs_tags.intersection(cell.get("metadata", {}).get("tags", []))
              and cell.cell_type == "code"
          ):
  
              cell.outputs = []
              cell.execution_count = None
              # Remove metadata associated with output
              if "metadata" in cell:
                  for field in self.remove_metadata_fields:
                      cell.metadata.pop(field, None)
  
          if self.remove_input_tags.intersection(cell.get("metadata", {}).get("tags", [])):
              cell.transient = {"remove_source": True}
  
          if cell.get("outputs", []):
              cell.outputs = [
                  output
                  for output_index, output in enumerate(cell.outputs)
                  if self.check_output_conditions(output, resources, cell_index, output_index)
              ]
          return cell, resources
  
      def check_output_conditions(self, output, resources, cell_index, output_index):
          """
          Checks that an output has a tag that indicates removal.
  
          Returns: Boolean.
          True means output should *not* be removed.
          """
          return not self.remove_single_output_tags.intersection(
              output.get("metadata", {}).get("tags", [])
          )
  