def filter(self, filter_by):
        """
        Returns a new bag containing only cells which match
        the filter_by predicate.

        filter_by can be:
        a) a callable, which takes a cell as a parameter
           and returns True if the cell should be returned,
           such as `lambda cell: cell value == 'dog'
        b) a string, to match exactly: `u'dog'`
        c) a hamcrest match rule: `hamcrest.equal_to("dog")
           (requires hamcrest to be available)
        d) a compiled regex: `re.compile("dog")
        """
        if callable(filter_by):
            return self._filter_internal(filter_by)
        elif isinstance(filter_by, six.string_types):
            return self._filter_internal(lambda cell: six.text_type(cell.value).strip() == filter_by)
        elif have_ham and isinstance(filter_by, hamcrest.matcher.Matcher):
            return self._filter_internal(lambda cell: filter_by.matches(cell.value))
        elif isinstance(filter_by, REGEX_PATTERN_TYPE):
            return self._filter_internal(
                lambda cell: re.match(filter_by, six.text_type(cell.value)))
        else:
            raise ValueError("filter_by must be function, hamcrest filter, compiled regex or string.")