Filter a list of resources according to a query expression.

    The search criteria specified in the query parameter has two parts:
      1. a VISA regular expression over a resource string.
      2. optional logical expression over attribute values
         (not implemented in this function, see below).

    .. note: The VISA regular expression syntax is not the same as the
             Python regular expression syntax. (see below)

    The regular expression is matched against the resource strings of resources
    known to the VISA Resource Manager. If the resource string matches the
    regular expression, the attribute values of the resource are then matched
    against the expression over attribute values. If the match is successful,
    the resource has met the search criteria and gets added to the list of
    resources found.

    By using the optional attribute expression, you can construct flexible
    and powerful expressions with the use of logical ANDs (&&), ORs(||),
    and NOTs (!). You can use equal (==) and unequal (!=) comparators to
    compare attributes of any type, and other inequality comparators
    (>, <, >=, <=) to compare attributes of numeric type. Use only global
    attributes in the attribute expression. Local attributes are not allowed
    in the logical expression part of the expr parameter.


        Symbol      Meaning
        ----------  ----------

        ?           Matches any one character.

        \           Makes the character that follows it an ordinary character
                    instead of special character. For example, when a question
                    mark follows a backslash (\?), it matches the ? character
                    instead of any one character.

        [list]      Matches any one character from the enclosed list. You can
                    use a hyphen to match a range of characters.

        [^list]     Matches any character not in the enclosed list. You can use
                    a hyphen to match a range of characters.

        *           Matches 0 or more occurrences of the preceding character or
                    expression.

        +           Matches 1 or more occurrences of the preceding character or
                    expression.

        Exp|exp     Matches either the preceding or following expression. The or
                    operator | matches the entire expression that precedes or
                    follows it and not just the character that precedes or follows
                    it. For example, VXI|GPIB means (VXI)|(GPIB), not VX(I|G)PIB.

        (exp)       Grouping characters or expressions.


    :param resources: iterable of resources.
    :param query: query expression.

def filter(resources, query):
    """Filter a list of resources according to a query expression.

    The search criteria specified in the query parameter has two parts:
      1. a VISA regular expression over a resource string.
      2. optional logical expression over attribute values
         (not implemented in this function, see below).

    .. note: The VISA regular expression syntax is not the same as the
             Python regular expression syntax. (see below)

    The regular expression is matched against the resource strings of resources
    known to the VISA Resource Manager. If the resource string matches the
    regular expression, the attribute values of the resource are then matched
    against the expression over attribute values. If the match is successful,
    the resource has met the search criteria and gets added to the list of
    resources found.

    By using the optional attribute expression, you can construct flexible
    and powerful expressions with the use of logical ANDs (&&), ORs(||),
    and NOTs (!). You can use equal (==) and unequal (!=) comparators to
    compare attributes of any type, and other inequality comparators
    (>, <, >=, <=) to compare attributes of numeric type. Use only global
    attributes in the attribute expression. Local attributes are not allowed
    in the logical expression part of the expr parameter.


        Symbol      Meaning
        ----------  ----------

        ?           Matches any one character.

        \           Makes the character that follows it an ordinary character
                    instead of special character. For example, when a question
                    mark follows a backslash (\?), it matches the ? character
                    instead of any one character.

        [list]      Matches any one character from the enclosed list. You can
                    use a hyphen to match a range of characters.

        [^list]     Matches any character not in the enclosed list. You can use
                    a hyphen to match a range of characters.

        *           Matches 0 or more occurrences of the preceding character or
                    expression.

        +           Matches 1 or more occurrences of the preceding character or
                    expression.

        Exp|exp     Matches either the preceding or following expression. The or
                    operator | matches the entire expression that precedes or
                    follows it and not just the character that precedes or follows
                    it. For example, VXI|GPIB means (VXI)|(GPIB), not VX(I|G)PIB.

        (exp)       Grouping characters or expressions.


    :param resources: iterable of resources.
    :param query: query expression.
    """

    if '{' in query:
        query, _ = query.split('{')
        logger.warning('optional part of the query expression not supported. '
                       'See filter2')

    try:
        query = query.replace('?', '.')
        matcher = re.compile(query, re.IGNORECASE)
    except re.error:
        raise errors.VisaIOError(constants.VI_ERROR_INV_EXPR)

    return tuple(res for res in resources if matcher.match(res))