2013-06-09 33 views
6

Tôi đang sử dụng dateutil để phân tích tên tệp hình ảnh và sắp xếp chúng theo ngày. Vì không phải tất cả các hình ảnh của tôi đều có siêu dữ liệu, dateutil đang cố gắng đoán vị trí của chúng.Trình phân tích cú pháp dateutil của Python, bỏ qua phần không phải là ngày của chuỗi

Hầu hết các hình ảnh của tôi là ở định dạng này: 2007-09-10_0001.jpg 2007-09-10_0002.jpg vv ...

fileName = os.path.splitext(file)[0] 
print("Guesssing date from ", fileName) 
try: 
    dateString = dateParser.parse(file, fuzzy=True) 
    print("Guessed date", dateString) 
    year=dateString.year 
    month = dateString.month 
    day=dateString.day 
except ValueError: 
    print("Unable to determine date of ", file) 

Sự trở lại tôi nhận được là:

('Guesssing date from ', '2007-09-10_00005') 
('Unable to determine date of ', '2007-09-10_00005.jpg') 

Bây giờ tôi có thể xóa mọi thứ từ sau dấu gạch dưới, nhưng tôi muốn có giải pháp mạnh mẽ hơn nếu có thể, trong trường hợp tôi có hình ảnh ở định dạng khác. Tôi mặc dù mờ sẽ cố gắng và tìm thấy bất kỳ ngày nào trong chuỗi và phù hợp với điều đó, nhưng dường như không hoạt động ...

Có cách nào dễ dàng để trình phân tích cú pháp tìm thấy bất kỳ thứ gì giống như ngày và dừng sau đó không? Nếu không, cách dễ nhất để buộc trình phân tích cú pháp bỏ qua mọi thứ sau dấu gạch dưới là gì? Hoặc một cách để xác định nhiều định dạng ngày với các phần bỏ qua.

Cảm ơn!

+0

là ngày của bạn ít nhất bằng cách nào đó được định dạng? Giống như "yyyy-mm-dd ở đâu đó trong tên tệp"? – mishik

+0

Ý tôi là đôi khi bạn sẽ không thể phân biệt tháng và ngày nếu định dạng ngày là yyyy-dd-mm hoặc yyyy-mm-dd. – mishik

+0

@mishik Có, nó thường là một cái gì đó như "2007-09-10" trong một tên tập tin đầy đủ của "2007-09-10_001". Nếu tôi tẩy "_001" khỏi chuỗi, nó sẽ nhận ra ngày tháng tốt. – deranjer

Trả lời

4

Bạn có thể cố gắng "giảm" chuỗi miễn là bạn không thể giải mã nó:

from dateutil import parser 

def reduce_string(string): 
    i = len(string) - 1 
    while string[i] >= '0' and string[i] < '9': 
     i -= 1 
    while string[i] < '0' or string[i] > '9': 
     i -= 1 
    return string[:i + 1] 

def find_date(string): 
    while string: 
     try: 
      dateString = parser.parse(string, fuzzy=True) 
      year = dateString.year 
      month = dateString.month 
      day = dateString.day 
      return (year, month, day) 
     except ValueError: 
      pass 

     string = reduce_string(string) 

    return None 

date = find_date('2007-09-10_00005') 
if date: 
    print date 
else: 
    print "can't decode" 

Ý tưởng là để loại bỏ phần cuối của chuỗi (bất kỳ số sau đó bất kỳ không số) cho đến khi trình phân tích cú pháp có thể giải mã nó thành một ngày hợp lệ.

+0

Cảm ơn! Có vẻ như đó sẽ là giải pháp tốt nhất cho tôi, cũng cảm ơn vì đã viết mã ra .. rất mới cho python (và lập trình) và điều đó sẽ khiến tôi mất một thời gian để tìm ra: D – deranjer

2

Nhận xét từ tương lai tại đây, như một số thông tin chi tiết hơn về vấn đề này.

Trong khi tìm kiếm mờ của dateutil là khá tốt khi chọn ngày bằng ngôn ngữ tự nhiên bình thường, nó không thành công ở chuỗi như trên với tấn nhiễu liên quan đến số/ký hiệu. Với nhiều phiên bản gần đây của dateutil, tuy nhiên, khi chạy:

>>> from dateutil.parser import parse 
>>> parse('2007-09-10_00005.jpg', fuzzy=True) 

parse không thành công với TypeError: 'NoneType' object is not iterable, mà không phải là rất thành ngữ.

Một lựa chọn khác đơn giản là tìm kiếm định dạng ngày đã biết bằng regex. Tất nhiên, điều này thay đổi theo từng trường hợp sử dụng, nhưng OP nói rằng ngày của ông là luôn theo định dạng YYYY-MM-DD, mà làm cho nó lý tưởng cho một tìm kiếm regex:

from dateutil.parser import parse 
import re 

date_pattern = re.compile('\d{4}-\d{2}-\d{2}') 

def extract_date(filename): 
    matches = re.match(date_pattern, filename) 
    if matches: 
     return parse(matches.group(0)) 
    else: 
     return None 

extract_date('2007-09-10_00005.jpg') # datetime.datetime(2007, 9, 10, 0, 0) 
Các vấn đề liên quan