2017-03-09 49 views
-1

说,例如,我有以下字符串和输入4.0,它代表秒:Python:如何只添加/减去一个数字字符串中的数字字符?

John Time Made 11:05:20 in 2010 
5.001 Kelly #1 
6.005 Josh #8 

,并希望以下结果:

John Time Made 11:05:24 in 2010 #Input 4.0 is added to the seconds of 11:05:20 
1.001 Kelly #1 #4.0 is subtracted from the first number 5.001 = 1.001 
2.005 Josh #8 #4.0 is subtracted from the first number 5.001 = 2.005 

我怎么能认识到hours:minutes:seconds第一行,并在其余的#.###添加/减去输入数字?

谢谢你在前进,并会接受/给予好评回答

+0

到目前为止您尝试过什么? – lordingtar

+0

尝试使用正则表达式。 –

+0

第二行和第三行的数字代表什么?还有时间或浮点数? – lmichelbacher

回答

0

如果您完整的内容具有相同的格式,你提供的这个特殊的样本这个解决方案应该工作。你应该在input.txt文件中有数据。

val_to_add = 4 

with open('input.txt') as fin: 
    # processing first line 
    first_line = fin.readline().strip() 
    splitted = first_line.split(' ') 

    # get hour, minute, second corresponding to time (11:05:20) 
    time_values = splitted[3].split(':') 

    # seconds is the last element 
    seconds = int(time_values[-1]) 

    # add the value 
    new_seconds = seconds + val_to_add 

    # doing simple math to avoid having values >= 60 for minute and second 
    # this part probably can be solved with datetime or some other lib, but it's not that complex, so I did it in couple of lines 
    seconds = new_seconds % 60 # if we get > 59 seconds we only put the modulo as second and the other part goes to minute 
    new_minutes = int(time_values[1]) + new_seconds // 60 # if we have more than 60 s then here we'll add minutes produced by adding to the seconds 
    minutes = new_minutes % 60 # similarly as for seconds 
    hours = int(time_values[0]) + new_minutes // 60 

    # here I convert again to string so we could easily apply join operation (operates only on strings) and additionaly add zero in front for 1 digit numbers 
    time_values[0] = str(hours).rjust(2, '0') 
    time_values[1] = str(minutes).rjust(2, '0') 
    time_values[2] = str(seconds).rjust(2, '0') 

    new_time_val = ':'.join(time_values)# join the values to follow the HH:MM:SS format 
    splitted[3] = new_time_val# replace the old time with the new one (with the value added) 
    first_line_modified = ' '.join(splitted)# just join the modified list 

    print(first_line_modified) 

    # processing othe lines 
    for line in fin: 
     # here we only get the first (0th) value and subtract the val_to_add and round to 3 digits the response (to avoid too many decimal places) 
     stripped = line.strip() 
     splitted = stripped.split(' ') 
     splitted[0] = str(round(float(splitted[0]) - val_to_add, 3)) 
     modified_line = ' '.join(splitted) 
     print(modified_line) 
+0

在我接受答案之前,您能否简要评论澄清和学习目的? –

+0

我用评论更新了答案 – giliev

+0

欣赏它!在round(float(splitted [0]) - val_to_add,3)中,它显示3位小数,但在某些情况下,如果它以0结尾,则会被截断并仅显示2.我怎样才能使它即使有尾随0,它仍然显示? –

0

虽然regex在评论气馁,regex可以使用的时间对象解析成datetime.time对象,对他们进行必要的计算,然后将其打印需要的格式:

# datetime module for time calculations 
import datetime 
# regex module 
import re 

# seconds to add to time 
myinp = 4 

# List of data strings 
# data = 'John Time Made 11:05:20 in 2010', '5.001 Kelly', '6.005 Josh' 

with open('data.txt') as f: 
    data = f.readlines() 

new_data = [] 

#iterate through the list of data strings 
for time in data: 
    try: 
     # First check for 'HH:MM:SS' time format in data string 
     # regex taken from this question: http://stackoverflow.com/questions/8318236/regex-pattern-for-hhmmss-time-string 
     match = re.findall("([0-1]?\d|2[0-3]):([0-5]?\d):([0-5]?\d)", time) 
     # this regex returns a list of tuples as strings "[('HH', 'MM', 'SS')]", 
     # which we join back together with ':' (colon) separators 
     t = ':'.join(match[0]) 
     # create a Datetime object from indexing the first matched time in the list, 
     # taken from this answer http://stackoverflow.com/questions/100210/what-is-the-standard-way-to-add-n-seconds-to-datetime-time-in-python 
     # May create an IndexError exception, which we catch in the `except` clause below 
     orig = datetime.datetime(100,1,1,int(match[0][0]), int(match[0][1]), int(match[0][2])) 
     # Add the number of seconds to the Datetime object, 
     # taken from this answer: http://stackoverflow.com/questions/656297/python-time-timedelta-equivalent 
     newtime = (orig + datetime.timedelta(0, myinp)).time() 
     # replace the time in the original data string with the newtime and print 
     new_data.append(time.replace(t, str(newtime))) 
    # catch an IndexError Exception, which we look for float-formatted seconds only 
    except IndexError: 
     # look for float-formatted seconds (s.xxx)  
     # taken from this answer: http://stackoverflow.com/questions/4703390/how-to-extract-a-floating-number-from-a-string 
     match = re.findall("\d+\.\d+", time) 
     # create a Datetime object from indexing the first matched time in the list, 
     # specifying only seconds, and microseconds, which we convert to milliseconds (micro*1000) 
     orig = datetime.datetime(100,1,1,second=int(match[0].split('.')[0]),microsecond=int(match[0].split('.')[1])*1000) 
     # Subtract the seconds from the Datetime object, similiar to the time addtion in the `try` clause above 
     newtime = orig - datetime.timedelta(0, myinp) 
     # format the newtime as `seconds` concatenated with the milliseconds converted from microseconds 
     newtime_fmt = newtime.second + newtime.microsecond/1000000. 
     # Get the seconds value (first value(index 0)) from splitting the original string at the `space` between the `seconds` and `name` strings 
     t = time.split(' ')[0] 
     # replace the time in the original data string with the newtime and print 
     new_data.append(time.replace(t , str(newtime_fmt))) 


with open('new_data.txt', 'w') as nf: 
    for newline in new_data: 
     nf.write(newline) 

new_data.txt文件内容应看作:

John Time Made 11:05:24 in 2010 
1.001 Kelly 
2.005 Josh 
+0

为了学习的目的和理解,你可以简单地评论一下吗?先谢谢你! –

+0

完成。当然,很高兴帮助! – davedwards

+0

欣赏它!但我实际上正在阅读一个文件,其中包含该内容为例。 –