2009-03-09 19 views
12

Chcę uzyskać tylko nazwę pliku przy użyciu regex, więc starałem prostych rzeczy jakRegex: Uzyskaj nazwę pliku bez rozszerzenia w jednym ujęciu?

([^\.]*) 

które z pracy oczywiście tylko wtedy, gdy nazwa pliku ma jedno rozszerzenie. Ale jeśli jest to adfadsfads.blah.txt po prostu chcę adfadsfads.blah. Jak mogę to zrobić w przypadku wyrażenia regularnego?

Jeśli chodzi o pytanie Davida: "dlaczego użyłbyś regex", odpowiedź brzmi "dla zabawy". W rzeczywistości, kod używam jest prosta

length_of_ext = File.extname(filename).length 
filename = filename[0,(filename.length-length_of_ext)] 

ale chciałbym dowiedzieć się regex gdy jest to możliwe, ponieważ zawsze pojawia się na Geek koktajle.

+0

Daniel, w takim przypadku polecam zakup narzędzi takich jak RegexBuddy. Bardziej zabawnie jest grać z wyrażeniem regularnym, jeśli masz takie narzędzie. Można nawet debugować wyrażeń regularnych w takim narzędziu. Naprawdę to polecam. –

+0

Dzięki David. Używam Regex Coacha, co jest naprawdę przyjemne. –

Odpowiedz

33

Spróbuj tego:

(.+?)(\.[^.]*$|$) 

będzie to:

  • Przechwytywanie nazwy plików rozpoczynające się kropką (np ".logs" jest plik o nazwie ".logs", a nie rozszerzenie pliku), co jest powszechne w systemie Unix.
  • Pobiera wszystko oprócz ostatniej kropki: "foo.bar.jpeg" pobiera "foo.bar".
  • Obsługuje pliki bez kropki: "sekretna litera" dostaje "tajną literę".

Uwaga: jako komentator j_random_hacker zasugerował, to działa jak reklamowane, ale warto poprzedzać rzeczy z kotwicą dla celów czytelności.

+1

Jest to dobre wytłumaczenie na http://www.movingtofreedom.org/2008/04/01/regex-match-filename-base-andextext/ – bernie

+0

Gwiazda powinna być plusem, jak sądzę - choć nie jest jasne, co to jest plik o nazwie "log". powinien powrócić. –

+1

Chociaż działa to tak, jak w reklamie, czy mogę zaproponować umieszczenie kotwicy "^" tylko dla dobra czytelnictwa? Bez kotwicy programista, który po raz pierwszy zobaczy to wyrażenie, musi przeprowadzić szczegółową analizę, aby sprawdzić, czy zwrócony argument zawsze zaczyna się od początku łańcucha. –

4

Wszystko następuje kropka, a następnie przez jeden lub więcej znaków, które nie jest kropka, a następnie ciąg end-of-:

(.+?)\.[^\.]+$ 

wszystko-przed-the-last-kropka są pogrupowane na łatwy wyszukiwanie.

Jeżeli nie jesteś w 100% pewien, każdy plik będzie miał rozszerzenie, spróbuj:

(.+?)(\.[^\.]+$|$) 
+0

Nie pasuje do nazwy pliku, która nie ma rozszerzenia –

3

jak o 2 oddaje do jednego końca i jeden dla pliku.

np.

(.+?)(?:\.[^\.]*$|$) 
+0

Wszystko w porządku, ale ponieważ będę wyrzucać nazwę pliku, po co zawracać sobie głowę? Chciałbym wyrażeń regularnych, które po prostu pobierają nazwę pliku. –

+0

Ten również nie będzie zgodny z nazwą pliku bez rozszerzenia. –

0

OK, nie jestem pewien, dlaczego użyłbym tego wyrażenia regularnego. Jeśli wiem na przykład, że ciąg znaków jest pełną ścieżką do pliku, to chciałbym użyć innego interfejsu API, aby uzyskać nazwę pliku. Wyrażenia regularne są bardzo potężne, ale jednocześnie dość złożone (właśnie to udowodniłeś, pytając, jak stworzyć takie proste wyrażenie regularne). Ktoś powiedział: miałeś problem, że zdecydowałeś się go rozwiązać za pomocą wyrażeń regularnych. Teraz masz dwa problemy.

Pomyśl jeszcze raz. Jeśli na przykład korzystasz z platformy .NET, spójrz na klasę System.IO.Path.

+0

Cóż, to nie jest zabawne, prawda? W każdym razie, dostosuj pytanie do swojej odpowiedzi, patrz wyżej. Dzięki. –

0
^(.*)\\(.*)(\..*)$ 
  1. uzyskuje ścieżkę bez ostatniego \
  2. plik bez rozszerzenia
  3. rozszerzenie z .

Przykłady:

c:\1\2\3\Books.accdb
(c:\1\2\3)(Books)(.accdb)

nie obsługuje wielu . w nazwie pliku obsługuje . w ścieżce pliku

0

użyłem tego wzoru dla prostego wyszukiwania:

^\s*[^\.\W]+$ 

dla tego tekstu:

file.ext 
    fileext 

    file.ext.ext 
file.ext 
fileext 

Wyszukuje fileext w drugiej i ostatniej linii.
Zastosowałem go w widoku drzewa folderów (ze spacjami jako wcięcia).

Powiązane problemy