Поскольку каждый глоб может быть записан как регулярное выражение, и можно найти пересечение двух регулярных выражений (если они не являются на самом деле регулярными, но в этом случае они будут), вы можете найти пересечение двух глобусов с помощью превращая их в регулярные выражения, а затем находя пересечение тех. Таким образом, вы можете узнать, пересекаются ли два глоба, найдя пересечение регулярных выражений и проверив, пусто ли оно.
Однако, поскольку глобусы более ограничены, чем регулярное выражение, есть намного более простой способ:
Давайте назовем два глоба g1 и g2. Они пересекаются, если
- И g1, и g2 пусты или содержат только символы подстановки.
- Ни g1, ни g2 не пусты, и выполняется одно из следующих условий (пусть c1 будет первым символом g1, а t1 - строка, содержащая оставшиеся символы - то же самое для g2 с c2 и t2):
- c1 и c2 равны, а t1 и t2 пересекаются
- c1 и / или c2 является подстановочным знаком, а t1 пересекается с g2
- c1 и / или c2 является подстановочным знаком, а g1 пересекается с t2
Пример реализации в haskell:
intersect g1 [] = all (== '*') g1
intersect [] g2 = all (== '*') g2
intersect g1@('*':t1) g2@(c2:t2) = intersect g1 t2 || intersect t1 g2
intersect g1@(c1:t1) g2@('*':t2) = intersect t1 g2 || intersect g1 t2
intersect (c1:t1) (c2:t2) = c1 == c2 && intersect t1 t2
Этот алгоритм не особенно эффективен, если глобусы содержат много подстановочных знаков, но его очень легко реализовать, и, поскольку вы, вероятно, планируете использовать его с именами файлов, я сомневаюсь, что у вас будут глобусы длиннее 1000 символов.