2017-08-09 4 views
2

Elixir fournit Path.wildcard, qui utilise la fonction Erlang :filelib.wildcard en interne.Comment effectuer une recherche de fichier insensible à la casse dans Erlang/Elixir

La correspondance est sensible à la casse, par exemple, "a" ne correspond pas à "A". (http://erlang.org/doc/man/filelib.html#wildcard-1)

S'il vous plaît est-il insensible à la cassealternative?

+1

Je ne pense pas qu'il y ait une façon de le faire avec cette fonction. Si le répertoire racine n'est pas trop grand, vous pouvez récupérer la liste entière et filtrer en utilisant une regex insensible à la casse. – Dogbert

+0

aurait été propre si nous pouvions utiliser les [options] pour spécifier: case_insensitive –

+0

En fait, vous pouvez faire une simple transformation de chaîne, en remplaçant toutes les lettres avec sa version inférieure et majuscule entre crochets, par exemple. 'abc' ->' [aA] [bB] [cC] '. Je posterai une réponse dans quelques minutes. – Dogbert

Répondre

3

Il n'existe pas d'option intégrée pour cela, mais comme la syntaxe générique prend en charge les alternances de caractères similaires à regex, vous pouvez remplacer chaque lettre par une alternance de ses versions majuscules et minuscules, par ex. f0o ->[fF]0[oO], puis passez à Path.wildcard/1. Voici une implémentation simple qui fait cela pour les lettres ASCII:

defmodule A do 
    def case_insensitive_glob(glob) do 
    Regex.replace(~r/[a-zA-Z]/, glob, fn letter -> 
     "[#{String.downcase(letter)}#{String.upcase(letter)}]" 
    end) 
    end 
end 

glob = A.case_insensitive_glob("**/*reAdmE.*") |> IO.inspect 
Path.wildcard(glob) |> IO.inspect 

L'exécution de ce dans le code source OTP produit tous les fichiers avec leur nom contenant « Readme. » dans tout les cas.

"**/*[rR][eE][aA][dD][mM][eE].*" 
["README.md", "erts/emulator/pcre/README.pcre_update.md", 
"lib/erl_interface/src/README.internal", 
"lib/ic/examples/pre_post_condition/ReadMe.txt", "xcomp/README.md"] 

J'ai vérifié l'exactitude de la sortie avec find:

$ find . -iname 'readme.*' 
./erts/emulator/pcre/README.pcre_update.md 
./lib/erl_interface/src/README.internal 
./lib/ic/examples/pre_post_condition/ReadMe.txt 
./README.md 
./xcomp/README.md 
+0

c'est un truc génial! –

+0

Je crois que nous pourrions échapper le chemin entier avec cette fonction insensible à la casse et l'appliquer à Path.wildcard d'Elixir, si une option case_insensitive est choisie. Serait-ce cher? –

+3

Si jamais Elixir ajoute cette fonctionnalité, ils voudront probablement aussi prendre en charge les lettres Unicode et remplacer le 'Regex.replace' par une alternative roulée à la main qui utilise récursivité + correspondance de modèle pour effectuer le remplacement, pour les performances. – Dogbert