2017-02-22 23 views
1

Я пытаюсь извлечь некоторые данные из пользовательского ввода, которые должны следовать этому формату: 1d 5h 30m, что означает, что пользователь вводит количество времени 1 день, 5 часов и 30 минут.JavaScript regex: захват необязательных групп при строгого соответствия

Я пытаюсь извлечь значение каждой части ввода. Однако каждая группа является необязательной, то есть 2h 20m является допустимым вводом.

Я стараюсь быть гибким во входном (в том смысле, что не все части должны быть введены), но в то же время я не наблюдаю, чтобы мое регулярное выражение соответствовало некоторому случайному вхождению, например asdfasdf20m. Этот должен быть отклонен (нет соответствия).

Так первый я избавлении от любого сепаратора пользователь мог бы использовать (их ввод может выглядеть 4h, 10m и это нормально):

input = input.replace(/[\s.,;_|#-]+/g, ''); 

Тогда я захватывая каждую часть, которую я указать в качестве дополнительного использования ?:

var match = /^((\d+)d)?((\d+)h)?((\d+)m)?$/.exec(input); 

это своего рода грязного захвата целой группы, включая письмо, когда я только хочу фактическое значение, но я не могу сказать, что кластер является необязательным, не окружив его с помощью скобок верно?

Затем, когда пустая группа фиксируется, ее значение в match равно undefined. Есть ли функция для значений по умолчанию undefined для определенного значения? Например, здесь будет удобно использовать 0.

Примера где input является "4d, 20h, 55m" и match результата:

["4d20h55m", "4d", "4", "20h", "20", "55m", "55", index: 0, input: "4d20h55m"] 

Моими основными вопросов:

  • Как я могу указать группу, как дополнительные, но избежать захвата его?

  • Как я могу обрабатывать входные данные, которые могут потенциально совпадать, например abcdefg6d8m?

  • Как я могу справиться с измененным заказом? Например, пользователь может ввести 20m 10h.

Когда я спрашиваю «как бороться с x», я имею в виду, что я хотел бы иметь возможность отклонить те соответствия.

+0

Возможно, вам захочется взглянуть на группы, не содержащие захват ['(?: Pattern)'] (http://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-what- делает-а-знак вопроса, а затем-на-а-ободочной кишки). –

+0

Что касается «Как я могу справиться с измененным порядком?» как вы хотите, чтобы иметь дело с этим?Является ли это '20m 10h' действительным или оно должно быть отклонено? Как насчет '4d 5d 6d'? Будет ли это отвергнуто прямо? Как насчет '4D 5H 6M' или' 100000m 1s'? –

+0

А какие ограничители допускаются? '1d, 1h' разрешен, но разрешен ли« 1d: 1h »? Как насчет '1d, 1h,' (трейлинг-разделитель), '1d% 1h' или' 1d1h'? –

ответ

0

Как вариант:

HTML:

<input type="text"> 
<button>Check</button> 
<div id="res"></div> 

JS:

var r = []; 
document.querySelector('button').addEventListener('click', function(){ 
    var v = document.querySelector('input').value; 
    v.replace(/(\d+d)|(\d+h)|(\d+m)/ig, replacer); 
    document.querySelector('#res').innerText = r; 
}, false); 

function trim(s, mask) { 
    while (~mask.indexOf(s[0])) { 
     s = s.slice(1); 
    } 
    while (~mask.indexOf(s[s.length - 1])) { 
     s = s.slice(0, -1); 
    } 
    return s; 
} 

function replacer(str){ 
    if(/d$/gi.test(str)){ 
    r[0] = str; 
    } 
    else if(/h$/gi.test(str)){ 
    r[1] = str; 
    } 
    else if(/m$/gi.test(str)){ 
    r[2] = str; 
    } 
    return trim(r.join(', '), ','); 
} 

См here.