2013-06-09 10 views
6

के गैर-तारीख भाग को अनदेखा करें, मैं चित्र फ़ाइल नामों को पार्स करने के लिए डेट्यूटिल का उपयोग कर रहा हूं और उन्हें तिथि के अनुसार क्रमबद्ध करता हूं। चूंकि मेरी सभी तस्वीरों में मेटाडेटा नहीं है, डेटटाइल यह अनुमान लगाने की कोशिश कर रहा है कि उन्हें कहां रखा जाए।पायथन डेट्यूटिल पार्सर, स्ट्रिंग

मेरी तस्वीरें से अधिकांश इस प्रारूप में हैं: 2007-09-10_0001.jpg 2007-09-10_0002.jpg आदि ...

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) 

वापसी मैं हो रही है यह है:

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

अब मुझे अंडरस्कोर के बाद से सब कुछ पट्टी करने में सक्षम होना चाहिए, लेकिन यदि संभव हो तो मैं एक और प्रारूप में चित्रों के मामले में एक और मजबूत समाधान चाहता था। हालांकि मैं अस्पष्ट कोशिश करता हूं और स्ट्रिंग में किसी भी तारीख को ढूंढता हूं और उससे मेल खाता हूं, लेकिन स्पष्ट रूप से काम नहीं कर रहा है ...

क्या पार्सर को किसी तारीख की तरह दिखने और उसके बाद रुकने का कोई आसान तरीका है? यदि नहीं, तो पार्सर को अंडरस्कोर के बाद सब कुछ अनदेखा करने के लिए मजबूर करने का सबसे आसान तरीका क्या है? या अनदेखा अनुभागों के साथ कई दिनांक प्रारूपों को परिभाषित करने का एक तरीका।

धन्यवाद!

+0

अपनी तिथि कम से कम किसी भी तरह से स्वरूपित है? "Yyyy-mm-dd कहीं फ़ाइल नाम में" की तरह? – mishik

+0

मेरा मतलब यह है कि यदि आप दिनांक प्रारूप yyyy-dd-mm या yyyy-mm-dd है तो आप कभी-कभी महीने और दिनांक को अलग करने में सक्षम नहीं होंगे। – mishik

+0

@ मिशिक हां, यह आमतौर पर "2007-09-10_001" के पूर्ण फ़ाइल नाम में "2007-09-10" जैसा कुछ है। अगर मैं स्ट्रिंग से "_001" को शुद्ध करता हूं, तो यह तारीख को ठीक से पहचानता है। – deranjer

उत्तर

4

आप के रूप में आप इसे डिकोड नहीं कर सकता है जब तक स्ट्रिंग "को कम करने" करने की कोशिश कर सकते हैं:

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" 

विचार स्ट्रिंग के अंत (तो किसी भी संख्या किसी भी गैर-संख्या) जब तक दूर करने के लिए है पार्सर इसे वैध तिथि पर डीकोड कर सकता है।

+0

धन्यवाद! ऐसा लगता है कि यह मेरे लिए सबसे अच्छा समाधान होगा, कोड लिखने के लिए भी धन्यवाद .. पाइथन (और प्रोग्रामिंग) के लिए बहुत नया है और मुझे यह पता लगाने में थोड़ी देर लग गई होगी: डी – deranjer

2

इस समस्या में कुछ और अंतर्दृष्टि के रूप में यहां भविष्य से टिप्पणी करते हुए।

जबकि dateutil के फजी खोज सामान्य प्राकृतिक भाषा में दिनांक उठा पर बहुत अच्छा है, यह संख्यात्मक/प्रतीक संबंधित शोर के टन के साथ ऊपर की तरह तार पर विफल रहता है। dateutil के नवीनतम संस्करण, तथापि, जब चल रहा है के साथ:

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

parseTypeError: 'NoneType' object is not iterable साथ विफल रहता है, जो बहुत ही मुहावरेदार नहीं है।

एक और विकल्प बस रेगेक्स का उपयोग कर ज्ञात दिनांक प्रारूप की तलाश कर रहा है। बेशक, यह उपयोग के मामले से भिन्न होता है, लेकिन ओ पी उल्लेख किया है कि उसकी दिनांक स्वरूप YYYY-MM-DD है, जो यह एक 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) 
संबंधित मुद्दे