Как я могу проверить, относится ли строка к файлу или каталогу? с регулярными выражениями? в питоне?

поэтому я пишу общее приложение для резервного копирования с модулем os и pickle, и я пробовал приведенный ниже код, чтобы увидеть, является ли что-то файлом или каталогом (на основе ввода строки, а не его физического содержимого).

import os, re

def test(path):
    prog = re.compile("^[-\w,\s]+.[A-Za-z]{3}$")
    result = prog.match(path)
    if os.path.isfile(path) or result:
        print "is file"
    elif os.path.isdir(path):
        print "is directory"
    else: print "I dont know"

Проблемы

test("C:/treeOfFunFiles/")
is directory
test("/beach.jpg")
I dont know
test("beach.jpg")
I dont know
test("/directory/")
I dont know

Желаемый результат

test("C:/treeOfFunFiles/")
is directory
test("/beach.jpg")
is file
test("beach.jpg")
is file
test("/directory/")
is directory

Ресурсы

какое регулярное выражение я должен использовать, чтобы определить разницу между тем, что может быть file, и тем, что может быть directory? или есть другой способ сделать это?


person Killrawr    schedule 17.10.2012    source источник
comment
Для этого есть встроенные функции. Кроме того, вы, как правило, также хотите избегать использования регулярных выражений для управления путями. Они зависят не только от локали (например, символ иены в Японии в качестве разделителя пути), но и от ОС.   -  person kreativitea    schedule 17.10.2012
comment
Мне кажется, вы смешиваете две разные проблемы. Регулярные выражения не скажут вам, является ли файл каталогом или обычным файлом. Вместо этого вам нужно использовать os.path. См. это решение   -  person David    schedule 17.10.2012
comment
Кроме того, что, если у меня есть каталог с именем /beach.jpg?   -  person Joel Cornett    schedule 17.10.2012
comment
@ Джоэл, тогда тебе должно быть абсолютно стыдно, что у тебя такое смехотворно далекое соглашение об именах, которое бросает вызов всем законам логики и системам классификации регулярных выражений;)   -  person Jon Clements♦    schedule 17.10.2012
comment
@JonClements: нет, но я пытался указать на проблемы с использованием регулярных выражений для идентификации объектов файловой системы;)   -  person Joel Cornett    schedule 17.10.2012


Ответы (3)


В классе символов, если он присутствует и означает дефис, - должен быть либо первым/последним символом, либо экранированным \-, поэтому, например, измените "^[\w-,\s]+\.[A-Za-z]{3}$" на "^[-\w,\s]+\.[A-Za-z]{3}$".

В противном случае я думаю, что использование регулярных выражений для определения того, похоже ли что-то на имя файла/каталога, бессмысленно...

  • /dev/fd0 не является файлом или каталогом, например
  • ~/comm.pipe может выглядеть как файл, но это именованный канал
  • ~/images/test — это символическая ссылка на файл с именем «~/images/holiday/photo1.jpg».

Взгляните на модуль os.path, в котором есть функции, которые спрашивают ОС, что это такое...:

person Jon Clements♦    schedule 17.10.2012
comment
Спасибо +1 представителю, потому что вы показали мне, как использовать регулярное выражение в python :) - person Killrawr; 17.10.2012
comment
Я немного изменил свой исходный вопрос - person Killrawr; 17.10.2012
comment
@Killrawr is_dir = name[-1] in r'\/' ? Таким образом, все, что заканчивается разделителем пути (любого вида), просто рассматривается как каталог, иначе вы просто не знаете - person Jon Clements♦; 17.10.2012
comment
Спасибо, Джон, вывод 3 из 4, он знает, что это такое, но когда он доходит до чего-то вроде /beach.jpg, вывод возвращается как I dont know, не подберет ли RegEx этот файл, потому что у него есть .jpg ?? - person Killrawr; 17.10.2012
comment
@Killrawr ну, вы могли бы предположить, что все, что выглядит так, как будто у него есть расширение, является файлом, но тогда в системах Linux многие вещи не имеют расширений, но, скорее всего, являются файлами, в то время как другие вещи, которые выглядят так, как будто они могут есть удлинители, вполне могут быть специальные устройства/трубы/другое... - так что вы так или иначе ошибетесь, но если вас это устраивает - вы можете выбрать, как вы хотите это сделать, и будь на своей спине! - person Jon Clements♦; 17.10.2012
comment
path = "\\xmls\\" дает I don't know !!! - person user366312; 10.04.2021

Модуль os предоставляет методы для проверки того, является ли путь файлом или каталогом. Рекомендуется использовать этот модуль вместо регулярных выражений.

>>> import os
>>> print os.path.isfile(r'/Users')
False
>>> print os.path.isdir(r'/Users')
True
person Mr. Squig    schedule 17.10.2012
comment
О, это даже лучше :), чем то, что я пытался сделать, лол :) - person Killrawr; 17.10.2012
comment
Это работает, но print os.path.isfile(r'/Users') не работает со строками, а только с фактическими файлами, которые можно открыть (open()). - person Killrawr; 17.10.2012
comment
Я не уверен, что понимаю. Если файл можно «открыть», он существует, иначе будет выдано исключение. Вы можете использовать блок try/except для проверки таким образом. - person Mr. Squig; 17.10.2012
comment
Моя проблема в том, что мое приложение будет читать строки из командной строки, и пользователь может захотеть восстановить файл, но этот файл может не существовать на жестком диске (есть только хэш). os.path.isfile()` вернет False (поскольку файл еще не существует). Но +1 представитель отличный ответ :) каждый день узнавайте что-то новое - person Killrawr; 17.10.2012

Это может кому-то помочь, у меня была точно такая же потребность, и я использовал следующее регулярное выражение, чтобы проверить, является ли входная строка каталогом, файлом или ни тем, ни другим: для общего файла:

^(\/+\w{0,}){0,}\.\w{1,}$

для общего каталога:

^(\/+\w{0,}){0,}$

Таким образом, сгенерированная функция Python выглядит так:

import os, re

def check_input(path):
    check_file = re.compile("^(\/+\w{0,}){0,}\.\w{1,}$")
    check_directory = re.compile("^(\/+\w{0,}){0,}$")
    if check_file.match(path):
        print("It is a file.")
    elif check_directory.match(path):
        print("It is a directory")
    else:
        print("It is neither")

Пример:

  • check_input("/foo/bar/file.xyz") печатает -> Является ли файлом
  • check_input("/foo/bar/directory") печатает -> Является каталогом
  • check_input("Случайная тарабарщина") печатает -> Это не

Этот уровень безопасности ввода может быть позже усилен встроенными функциями os.path.isfile() и os.path.isdir(), как любезно показал Mr.Squig, но я уверен, что этот предварительный тест может сэкономить вам несколько микросекунд и повысить производительность вашего скрипта.

PS: При использовании этого фрагмента кода я заметил, что пропустил огромный вариант использования, когда путь фактически содержит специальные символы, такие как тире «-», который широко используется. Чтобы решить эту проблему, я изменил \w{0,}, который указывает требование только буквенных слов с .{0,}, который является просто случайным символом. Это скорее обходной путь, чем решение. Но это все, что у меня есть на данный момент.

person Yondaime008    schedule 16.12.2015
comment
Я думаю, что вы оставляете ./toto.sh или ~/stuff позади, хотя - person statquant; 08.02.2018