Repository: kedro-org/kedro
File: kedro/io/data_catalog.py (Python)

Code before:
                f"Invalid regular expression provided: '{regex_search}'"
            ) from exc
        return [dset_name for dset_name in self._data_sets if pattern.search(dset_name)]

    def exists_in_catalog_config(self, dataset_name: str) -> bool:
        """Check if a dataset exists in the catalog as an exact match or if it matches a pattern."""
        if (
            dataset_name in self._data_sets
            or dataset_name in self._pattern_matches_cache
        ):
            return True
        matched_pattern = self.match_name_against_patterns(dataset_name)
        if matched_pattern:
            # cache the "dataset_name -> pattern" match
            self._pattern_matches_cache[dataset_name] = matched_pattern
            return True
        return False

    def match_name_against_patterns(self, dataset_name: str) -> str | None:
        """Match a dataset name against existing patterns"""
        # Loop through all dataset patterns and check if the given dataset name has a match.
        for pattern in self._sorted_dataset_patterns:
            result = parse(pattern, dataset_name)
            if result:
                return pattern
        return None

    def shallow_copy(self) -> DataCatalog:
        """Returns a shallow copy of the current object.

        Returns:
            Copy of the current object.
        """
        return DataCatalog(
            data_sets=self._data_sets,
            layers=self.layers,
            dataset_patterns=self.dataset_patterns,
        )

    def __eq__(self, other):
        return (self._data_sets, self.layers, self.dataset_patterns) == (
            other._data_sets,
            other.layers,
            other.dataset_patterns,
        )

    def confirm(self, name: str) -> None:
        """Confirm a dataset by its name.

        Args:
            name: Name of the dataset.

Review comment (refactor):
Is there a reason we need this separately from directly resolving upon check of existence? Could we just call this `resolve` and do all of the matching and calling the resolve helper here?

Code after:
            >>>
            >>> assert io.load("data").equals(df)
        """
        for data_set_name in feed_dict:
            if isinstance(feed_dict[data_set_name], AbstractDataSet):
                data_set = feed_dict[data_set_name]
            else:
                data_set = MemoryDataset(data=feed_dict[data_set_name])

            self.add(data_set_name, data_set, replace)

    def list(self, regex_search: str | None = None) -> list[str]:
        """
        List of all dataset names registered in the catalog.
        This can be filtered by providing an optional regular expression
        which will only return matching keys.

        Args:
            regex_search: An optional regular expression which can be provided
                to limit the data sets returned by a particular pattern.
        Returns:
            A list of dataset names available which match the
            `regex_search` criteria (if provided). All data set names are returned
            by default.

        Raises:
            SyntaxError: When an invalid regex filter is provided.

        Example:
        ::

            >>> io = DataCatalog()
            >>> # get data sets where the substring 'raw' is present
            >>> raw_data = io.list(regex_search='raw')
            >>> # get data sets which start with 'prm' or 'feat'
            >>> feat_eng_data = io.list(regex_search='^(prm|feat)')
            >>> # get data sets which end with 'time_series'
            >>> models = io.list(regex_search='.+time_series$')
        """

        if regex_search is None:
            return list(self._data_sets.keys())

        if not regex_search.strip():
            self._logger.warning("The empty string will not match any data sets")
            return []

        try:
            pattern = re.compile(regex_search, flags=re.IGNORECASE)

        except re.error as exc: