<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import re


def translate(pattern):
    r"""
    Given a glob pattern, produce a regex that matches it.

    &gt;&gt;&gt; translate('*.txt')
    '[^/]*\\.txt'
    &gt;&gt;&gt; translate('a?txt')
    'a.txt'
    &gt;&gt;&gt; translate('**/*')
    '.*/[^/]*'
    """
    return ''.join(map(replace, separate(pattern)))


def separate(pattern):
    """
    Separate out character sets to avoid translating their contents.

    &gt;&gt;&gt; [m.group(0) for m in separate('*.txt')]
    ['*.txt']
    &gt;&gt;&gt; [m.group(0) for m in separate('a[?]txt')]
    ['a', '[?]', 'txt']
    """
    return re.finditer(r'([^\[]+)|(?P&lt;set&gt;[\[].*?[\]])|([\[][^\]]*$)', pattern)


def replace(match):
    """
    Perform the replacements for a match from :func:`separate`.
    """

    return match.group('set') or (
        re.escape(match.group(0))
        .replace('\\*\\*', r'.*')
        .replace('\\*', r'[^/]*')
        .replace('\\?', r'.')
    )
</pre></body></html>