Size: a a a

2020 September 11

A

Alexander in DevOps
Sergei Puzyrev
котятки, у меня вопрос.

Допустим есть строка str, и два регэкспа regex1 и regex2.

всегда ли верно, что

(str ~ regex1) OR (str ~ regex2) == (str ~ concat(regex1, "|", regex2)) ?

Иными словами: эквивалентно ли утверждение "строка матчится хотя бы в один из регэкспов" утверждению "строка матчится в конкатенацию регэкспов через оператор |?
Если это не какой-то вопрос с подводим, то, наверное, да.
источник

SP

Sergei Puzyrev in DevOps
Alexander
Если это не какой-то вопрос с подводим, то, наверное, да.
это не вопрос с подвохом, я пытаюсь формально это доказать
источник

SP

Sergei Puzyrev in DevOps
то есть я не знаю, какой правильный ответ
источник

A

Alexander in DevOps
Sergei Puzyrev
то есть я не знаю, какой правильный ответ
Мне в голову лезет всякая функциональщина с карри-функциями и польской нотацией, но собрать из этого внятное доказательство не могу. :/ Да и насчёт представления регулярных выражений в виде функций сомнения мучают.
источник

SP

Sergei Puzyrev in DevOps
Alexander
Мне в голову лезет всякая функциональщина с карри-функциями и польской нотацией, но собрать из этого внятное доказательство не могу. :/ Да и насчёт представления регулярных выражений в виде функций сомнения мучают.
S='Hello, world'; R1="(?i)ELLA"; R2="ELL"; R3="${R1}|${R2}"; for re in $R1 $R2 $R3 ; do echo -en "${S} "; echo "$S" | grep -Pq "$re" && echo -en "matches" || echo -en "does not match"; echo " ${re}" ; done
Hello, world does not match (?i)ELLA
Hello, world does not match ELL
Hello, world matches (?i)ELLA|ELL
источник

SP

Sergei Puzyrev in DevOps
я нашёл контрпример
источник

A

Alexander in DevOps
Sergei Puzyrev
S='Hello, world'; R1="(?i)ELLA"; R2="ELL"; R3="${R1}|${R2}"; for re in $R1 $R2 $R3 ; do echo -en "${S} "; echo "$S" | grep -Pq "$re" && echo -en "matches" || echo -en "does not match"; echo " ${re}" ; done
Hello, world does not match (?i)ELLA
Hello, world does not match ELL
Hello, world matches (?i)ELLA|ELL
Да, с глобальные литералы меняют картину. Но твоё исходное утверждение этот пример не опровергает :)
источник

A

Alexander in DevOps
А, не, туплю, опрвергает
источник

A

Alexander in DevOps
@spuzirev а если тогда так:
concat("(", re1, ")|(", re2, ")")
источник

SP

Sergei Puzyrev in DevOps
проверь
источник

SP

Sergei Puzyrev in DevOps
мне нужно было просто коллеге доказать, что манипуляция литералами регэкспов потенциально небезопасна и может менять семантику.
источник

SP

Sergei Puzyrev in DevOps
🙂
источник

A

Alexander in DevOps
Ну ок
источник

SP

Sergei Puzyrev in DevOps
Alexander
@spuzirev а если тогда так:
concat("(", re1, ")|(", re2, ")")
есть подозрение что это тоже небезопасно
источник

A

Alexander in DevOps
Sergei Puzyrev
есть подозрение что это тоже небезопасно
Что угодно небезопасно, если в аргументах пользовательский ввод: sql-выражения, фильтры ldap, даже markdown :)
источник

A

Alexander in DevOps
Если же ты точно знаешь, что будет внутри, то вполне безопасно
источник

SP

Sergei Puzyrev in DevOps
Alexander
Если же ты точно знаешь, что будет внутри, то вполне безопасно
ну у меня там пользовательский ввод, но пользователь в принципе не злонамеренный.
источник

rd

rus dacent in DevOps
Sergei Puzyrev
S='Hello, world'; R1="(?i)ELLA"; R2="ELL"; R3="${R1}|${R2}"; for re in $R1 $R2 $R3 ; do echo -en "${S} "; echo "$S" | grep -Pq "$re" && echo -en "matches" || echo -en "does not match"; echo " ${re}" ; done
Hello, world does not match (?i)ELLA
Hello, world does not match ELL
Hello, world matches (?i)ELLA|ELL
Вот так правильней будет
R3="(${R1})|(${R2})";
тогда
Hello, world does not match (?i)ELLA
Hello, world does not match ELL
Hello, world does not match ((?i)ELLA)|(ELL)

иначе у тебя, как мне видится, не эквивалентное выражение подставляется.
источник

SP

Sergei Puzyrev in DevOps
rus dacent
Вот так правильней будет
R3="(${R1})|(${R2})";
тогда
Hello, world does not match (?i)ELLA
Hello, world does not match ELL
Hello, world does not match ((?i)ELLA)|(ELL)

иначе у тебя, как мне видится, не эквивалентное выражение подставляется.
мне тут подсказали еще пример с бэклинками: (?P<name>pattern)
источник

SP

Sergei Puzyrev in DevOps
import re

r1 = r'(?P<a>A)\1'
r2 = r'(?P<b>B)\1'

print(bool(re.match(r1, 'BB') or re.match(r2, 'BB')))  # True
print(bool(re.match(r1 + '|' + r2, 'BB')))  # False
источник