У меня есть следующий код в оболочке:
case ${daterange} in
*[Mm][Oo]*)
factor=2592000
;;
*[Ww]*)
factor=604800
;;
*[Dd]*)
factor=86400
;;
*[Hh]*)
factor=3600
;;
*)
factor=60
;;
esac
num='expr x"$TMFR" : x"[^0-9]*\([0-9]*\)"'
expr 0$num \* $factor
Я написал следующее, чтобы преобразовать его в python, но там, где я застрял, это строки num=
и expr
. Я не знаю, как перенести их на python.
if re.search(r'[Mm][Oo]', daterange):
print "A"
elif re.search(r'[Ww]', daterange):
print "B"
elif re.search(r'[Dd]', daterange):
print "C"
elif re.search(r'[Hh]', daterange):
print "D"
elif re.search(r'[Mm]', daterange):
print "E"
else:
print "F"
daterange
может содержать такие значения, как:
4h = which means 4 hours
4mo = which means 4 months
4w = which means 4 weeks
4d = which means 4 days
4m = which means 4 minutes
4s = which means 4 seconds
Цель здесь - принять значение в daterange
и перевести его на секунды.
expr
выполняет выражения:
expr x"$TMFR": x"[^0-9]*\([0-9]*\)"
соответствует строке x
за которой следует значение $TMFR
против выражения regulare x[^0-9]*([0-9]*)
, распечатывая часть между круглыми скобками (которые экранируются, чтобы предотвратить их интерпретацию bash вместо этого).expr 0$num \* $factor
умножает число $num
на $factor
, по умолчанию 0. Таким образом, он в основном находит первое числовое значение в строке $TMFR
и умножает это число на уже рассчитанный множитель.
Если у вас всегда есть число, за которым следует строка длительности, я бы просто использовал регулярное выражение для извлечения в оба раза и использовал словарь для сопоставления строки продолжительности с коэффициентом:
import re
durations = {
'mo': 2592000,
'w': 604800,
'd': 86400,
'h': 3600,
'm': 60,
's': 1
}
# match on digits followed directly by one of the duration strings, ignoring case
# the duration strings are sorted by descending length to ensure shorter
# sub-patterns are considered after the longer options (compare 'mo' and m')
pattern = re.compile(r'(\d+)({})\b'.format(
'|'.join(sorted(durations, key=len, reverse=True))),
flags=re.IGNORECASE)
def duration_from_string(s):
return sum(
int(m.group(1)) * durations[m.group(2)]
for m in pattern.finditer(s))
Я предположил, что вам нужно поддерживать промежуточные промежутки времени, разделенные пробелами, поэтому 1mo 2w 3d
составляет 4060800 секунд (1 месяц, 2 недели и 3 дня):
>>> duration_from_string('foo bar spam 1mo 2w 3d')
4060800
Если формат должен работать и без пробелов, оставьте привязку \b
от шаблона регулярного выражения.