Я пытаюсь понять, как все флаги регулярных выражений и побитовые связи связаны друг с другом. Единственное, что я действительно могу найти по этому поводу, это в документации , где говорится, что вы можете использовать Bitwise или '|' оператор. Я всегда использовал этот оператор при использовании флагов в прошлом, но я хочу знать, как он работает и в чем преимущество использования других операторов, таких как (&, ^, ~, >>, <<)
Насколько я понимаю, каждый флаг представляет собой значение?
print('{:>15} = {}'.format('re.ASCII', int(re.ASCII)))
print('{:>15} = {}'.format('re.DEBUG', int(re.DEBUG)))
print('{:>15} = {}'.format('re.IGNORECASE', int(re.IGNORECASE)))
print('{:>15} = {}'.format('re.LOCALE', int(re.LOCALE)))
print('{:>15} = {}'.format('re.MULTILINE', int(re.MULTILINE)))
print('{:>15} = {}'.format('re.DOTALL', int(re.DOTALL)))
print('{:>15} = {}'.format('re.VERBOSE', int(re.VERBOSE)))
> re.ASCII = 256
> re.DEBUG = 128
> re.IGNORECASE = 2
> re.LOCALE = 4
> re.MULTILINE = 8
> re.DOTALL = 16
> re.VERBOSE = 64
В чем будет разница в этих примерах:
re.compile('[\w]+', flags=(re.IGNORECASE | re.MULTILINE)
re.compile('[\w]+', flags=(re.IGNORECASE & re.MULTILINE)
re.compile('[\w]+', flags=(re.IGNORECASE ^ re.MULTILINE)
or
re.compile('[\w]+', flags=(re.DOTALL | re.MULTILINE)
re.compile('[\w]+', flags=(re.DOTALL & re.MULTILINE)
re.compile('[\w]+', flags=(re.DOTALL ^ re.MULTILINE)
Побитовая таблица для справки:
Это просто обычная практика использовать флаги. В программах на Python, C++, а может и в других, флаги обычно используются в таком стиле. Позволь мне привести пример.
re.compile('[\w]+', flags=(re.IGNORECASE | re.MULTILINE)
Когда вы устанавливаете флаги, как указано выше, это означает, что вы хотите применить обе эти настройки, а именно IGNORECASE и MULTILINE.
Я думаю, вы сбиты с толку, почему это будет применять оба параметра. Это связано с тем, что реинтерпретатор Python вполне может справиться с этим, как показано ниже:
if flags & re.IGNORECASE:
handle_in_ignorecase_way()
if flags & re.MULTILINE:
handle_in_multiline_way()
Вот почему флаги обычно устанавливаются в виде шаблонов, таких как 1, 2, 4, 8 и т. д., потому что реинтерпретатор может легко обрабатывать их, используя & и | когда пользователи дают несколько флагов. Флаги размещаются в разных битовых позициях, и их можно проанализировать с помощью простых битовых хаков.
Это просто побитовые операции. Используя эти конкретные значения, результат
&
всегда равен нулю, поскольку никакие два флага не имеют одинаковых битов, установленных в 1.^
отключит любые флаги, которые появляются четное количество раз в многочленном выражении.~
установит все не установленные флаги и удалит все установленные флаги. смещение здесь действительно бессмысленно, поскольку оно превращает флаги в другие флаги. Короче говоря, при использовании битовых флагов только использование|
имеет здесь логический смысл.