Quelle est l'expression régulière la plus correcte (regex) pour un chemin de fichier UNIX?
Par exemple, pour détecter quelque chose comme ceci:
/usr/lib/libgccpp.so.1.0.2
Il est assez facile de créer une expression régulière qui corresponde à la plupart des fichiers, mais quelle est la meilleure, notamment celle qui détecte les séquences d'espaces blancs échappés et les caractères inhabituels que vous ne trouvez généralement pas dans les chemins de fichiers sous UNIX.
De plus, existe-t-il des fonctions de bibliothèque dans plusieurs langages de programmation différents qui fournissent un regex de chemin de fichier?
Si vous ne craignez pas les faux positifs pour identifier les chemins, vous devez simplement vous assurer que le chemin ne contient pas de caractère NUL
; tout le reste est autorisé (en particulier, /
est le caractère séparateur de nom). La meilleure approche consisterait à résoudre le chemin indiqué à l’aide de la fonction fichier IO (par exemple, File.exists()
, File.getCanonicalFile()
en Java).
Réponse longue:
C'est à la foissystème d'exploitationetsystème de fichiersdépendant. Par exemple, la comparaison Wikipedia des systèmes de fichiers indique que, outre les limites imposées par le système de fichiers,
MS-DOS, Microsoft Windows et OS/2 Interdisent les caractères
\ / : ? * " > < |
etNUL
Dans le fichier et le répertoire Noms sur tous les systèmes de fichiers. Unices Et Linux interdisent les caractères/
EtNUL
dans les noms de fichiers et de répertoires Sur tous les systèmes de fichiers.
Sous Windows, les noms de périphérique reserved suivants ne sont également pas autorisés en tant que noms de fichiers:
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5,
COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4,
LPT5, LPT6, LPT7, LPT8, LPT9
L’expression régulière appropriée pour faire correspondre tous les chemins UNIX est: [^\0] +
C'est-à-dire un ou plusieurs caractères qui ne sont pas NUL.
Pour les autres personnes ayant répondu à cette question, il est important de noter que certaines applications nécessitent une expression régulière légèrement différente, en fonction de la manière dont les caractères d'échappement fonctionnent dans le programme que vous écrivez. Si vous écriviez un shell, par exemple, et souhaitez que les commandes soient séparées par des espaces et d'autres caractères spéciaux, vous devrez modifier votre expression rationnelle pour inclure uniquement les mots avec des caractères spéciaux si ces caractères sont masqués.
Ainsi, par exemple, un chemin valide serait
/ usr/bin/programme\avec\espace
par opposition à
/ usr/bin/programme avec espace
qui ferait référence à "/ usr/bin/programme" avec des arguments "avec" et "espace"
Une expression rationnelle pour l'exemple ci-dessus pourrait être "([^\0]\| \\) *"
La regex sur laquelle j'ai travaillé est (nouvelle ligne séparée pour "lisibilité"):
"\ (# Soit [^\0! $` & * () +] # Un caractère normal (non spécial) \| # Ou \\\ (\| \! |\$ |\'|\& |\* |\(| \) |\+ \) # Un caractère spécial échappé \)\+ "# Répété> = 1 fois
Ce qui se traduit par
"\ ([^\0! $` & * () +]\| \\\ (\ | \! |\$ |\| |\& \\ | |\| | | |\+ \) \)\+ "
Créer votre propre regex spécifique devrait également être relativement simple.
Je ne sais pas à quel point une vérification regex est courante dans tous les systèmes, mais la plupart des langages de programmation (notamment ceux multiplateformes) fournissent un contrôle "fichier existant" qui tiendra compte de ce genre de chose.
Par curiosité, où sont ces chemins entrés? Pourriez-vous contrôler cela plus en profondeur au point de ne plus avoir à vérifier les différentes parties du chemin? Par exemple, utiliser un dialogue de sélection de fichier?
^(/)?([^/\0]+(/)?)+$
Cela acceptera tous les chemins légaux dans les systèmes de fichiers tels que extX , reiserfs .
Il rejette uniquement les noms de chemin contenant le NUL ou une double barre (ou plus). Tout le reste selon les spécifications Unix devrait être légal (je suis aussi surpris de ce résultat).
Question déjà répondue ici: https://stackoverflow.com/a/42036026/1951947