2012-08-10 7 views
9

Próbuję przeanalizować ciąg wejściowy użytkownika na czas (w sekundach) z Javascriptem.Jak analizować łańcuch czasu trwania w kilka sekund za pomocą JavaScript?

Oto kilka przykładowych wejść że chciałbym być w stanie radzić sobie z:

  • "1 godzina, 2 minuty"
  • "1 dzień, 2 godziny, 3 minuty"
  • "1d 2h 37m"
  • "1 dzień 2min"
  • "3 dni 20hours"

kluczowe składniki 1) dni, 2) godzin 3) minut, ale niektóre składniki mogą nie zawsze być uwzględnione.

Mój plan ataku to użycie .match i regex. Dopóki mogę uzyskać pierwszą literę tego słowa, będę wiedział, do czego służy poprzedni numer i potrafię obsłużyć wszystkie formaty wyrazów (np. Godziny, godziny, godziny, h). Jednak, ponieważ uczę się tego za pomocą regex, okazało się, że jest znacznie bardziej skomplikowany, niż myślałem.

Każda pomoc lub sugestie będą bardzo mile widziane!

Odpowiedz

11

Czy zagwarantowana jest kolejność dni/godzin/minut w ciągu znaków? Jeśli nie, może być łatwiej po prostu zrobić osobne RegEx dla każdego. Coś takiego?

function getSeconds(str) { 
    var seconds = 0; 
    var days = str.match(/(\d+)\s*d/); 
    var hours = str.match(/(\d+)\s*h/); 
    var minutes = str.match(/(\d+)\s*m/); 
    if (days) { seconds += parseInt(days[1])*86400; } 
    if (hours) { seconds += parseInt(hours[1])*3600; } 
    if (minutes) { seconds += parseInt(minutes[1])*60; } 
    return seconds; 
} 
+0

To jest dokładnie to, czego szukałem. Radzi sobie z wszystkim, co do niego rzucam i jest bardzo czysty. Dzięki za tonę! –

+0

nie byłoby lepiej, aby zwrócić NaN na wypadek, gdyby nie było żadnego meczu, wiesz, aby ujednoznacznić? – Dan

1

można używać dodatkowych podciągów w regex dopasować dowolną kombinację, jak opisać:

/(\d+)\s*d(ays?)?\s*(\d+)\s*h(ours?)?\s*(\d+)\s*m(in(utes?)?)?/ 

Wymaga to przynajmniej d, h i m ale przyjmuje wspólne skróceń.

+0

Wygląda na to, że potrzebuje go do pracy, nawet jeśli nie wszystkie d, h i m są obecne. –

2

Można użyć tego kodu, aby złamać ciąg znaków na liczbę, a następnie ciąg jednostka:

function getPieces(str) { 
    var pieces = []; 
    var re = /(\d+)[\s,]*([a-zA-Z]+)/g, matches; 
    while (matches = re.exec(str)) { 
     pieces.push(+matches[1]); 
     pieces.push(matches[2]); 
    } 
    return(pieces); 
} 

Następnie funkcja zwraca tablicę takich jak ["1","day","2","hours","3","minutes"] którym elementy przemian w tablicy są wartością a następnie jednostkę dla tej wartości.

Więc za wyrażenie:

"1 day, 2 hours, 3 minutes" 

powraca funkcję:

[1, "day", 2, "hours", 3, "minutes"] 

Następnie można po prostu zbadać jednostki dla każdej wartości do decydowania, jak go obsłużyć.

Demo robocze i przypadki testowe tutaj: http://jsfiddle.net/jfriend00/kT9qn/. Funkcja toleruje zmienne ilości białych znaków i pobiera przecinek, spację lub nie pomiędzy cyfrą a etykietą jednostki. Oczekuje spacji lub przecinka (przynajmniej jednego) po jednostce.

+0

Bardzo ładnie _______. – some

1
var str = "1 day, 2 hours, 3 minutes"; 

var seconds = 0; 
str.replace (/\s*,?(\d+)\s*(?:(d)(?:ays?)?|(h)(?:ours?)?|(m)(?:in(?:utes?)?)?)/g, function (m0, n, d, h, m) { 
    seconds += +n * (d ? 24 * 60 * 60 : h ? 60 * 60 : 60); 
    return m0; 
}); 

Tutaj używam zamiast zamieniać ciąg, ale przetwarzać mecze jeden po drugim. Uwaga dni, godziny aminutes mogą być w dowolnej kolejności.

Powiązane problemy