проблема преобразования скрипта bash в python

1

У меня есть следующий код в оболочке:

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 и перевести его на секунды.

Теги:

1 ответ

1
Лучший ответ

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 от шаблона регулярного выражения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню