2015-06-07 5 views
11

Я видел много функций, которые форматируют телефон или номер (запятую и десятичные знаки) в сообществе stackflow, как этот вопрос here и другие. Вот что я хочу:JavaScript RegExp для автоматического форматирования Образец

Шаг 1: Поддерживать библиотеки для моделей, как это:

var library = { 
    fullDate : { 
     pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/, 
     error : "Invalid Date format. Use YYYY-MM-DD format." 
    }, 
    fullDateTime : { 
     pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}$/, 
     error : "Invalid DateTime format. Use YYYY-MM-DD HH:MM (24-hour) format." 
    }, 
    tel : { 
     pattern : /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/, 
     error : "Invalid Telephone format." 
    } 
}; 

Шаг 2: Автоматически добавить символ, как они печатают. Например, добавьте - после 4 цифр в Date.

У меня есть текстовое поле сказать:

<input type="text" data-validate="fullDate" placeholder="YYYY-MM-DD"/> 

И возможно место, чтобы начать сценарий как:

$('body').on('keyup','input',function(){ 
    var validate = $(this).data('validate'); 
    var pattern = library[validate].pattern; 


    //Some more steps here.... 

}); 

Но я не могу сделать дальше, потому что я новичок в RegExp. Вот startup fiddle. Кто угодно?

Дальнейшие Примечания: Я был в состоянии проверить с помощью следующих функций, но то, что я хочу, чтобы автоматически сделать шаблон:

function validate(libraryItem, subject){ 
    var item = library[libraryItem]; 
    if(item !== undefined){ 
     var pattern = item.pattern; 
     if(validatePattern(pattern, subject)){ 
      return true; 
     } else { 
      return item.error; 
     } 
    } 
    return false; 
} 


function validatePattern(pattern, subject){ 
    return pattern.test(subject); 
} 
+1

Регулярные выражения для проверки правильны, но они не подходят для внесения предложений ... для этого вам понадобится какой-то государственный автомат. –

ответ

6

Это не так сложно, как вы думаете. Вы ищете JQuery Masked ввода и другие альтернативные библиотеки. Вот documentation.Все, что вам нужно:

<input id="date" type="text" placeholder="YYYY-MM-DD"/> 

и сценарий:

$("#date").mask("9999-99-99",{placeholder:"YYYY-MM-DD"}); 

Вот демонстрационная ручка ссылка: http://codepen.io/anon/pen/gpRyBp

Для реализации используется проверка этой библиотеки: https://github.com/RobinHerbots/jquery.inputmask

+0

Можете ли вы позаботиться о переменном количестве цифр? Можем ли мы сделать часть строки необязательной. Можете ли вы убедиться, что принят правильный номер месяца, номер даты. –

+0

@AnuragPeshne Используйте https://github.com/bseth99/sandbox/blob/master/projects/jquery-ui/5-jquery-masks.html для проверки. Описание находится здесь http://bseth99.github.io/projects/jquery-ui/5-jquery-masks.html, а ссылка github - https://github.com/RobinHerbots/jquery.inputmask –

2

Что нужно здесь разбивая регулярное выражение в подэкранном выражение, которое соответствует части строка и предложить завершение на основе следующего символа в регулярном выражении. Я написал наивный парсер, который анализирует выражение и делит его на атомное подвыражение.

var parser = function(input) { 
    var tokenStack = []; 
    var suggestions = []; 
    var suggestion; 
    var lookAhead; 

    if (input[0] === '/') 
     input = input.slice(1, input.length - 1); 

    var i; 
    for (i = 0; i < input.length - 1; i++) { 
     lookAhead = input[i + 1]; 
     switch (input[i]) { 
     case '(': 
      tokenStack.push('('); 
      break; 
     case '[': 
      tokenStack.push('['); 
      break; 
     case ')': 
      if (tokenStack[tokenStack.length - 1] === '(') { 
       tokenStack.pop(); 
       if (tokenStack.length === 0) { 
        suggestion = generateSuggestion(input, i); 
        if (suggestion !== null) 
         suggestions.push(suggestion); 
       } 
      } 
      else 
       throw 'bracket mismatch'; 
      break; 
     case ']': 
      if (lookAhead === '{') { 
       while (input[i] !== '}') 
        i++; 
      } 
      if (tokenStack[tokenStack.length - 1] === '[') { 
       tokenStack.pop(); 
       if (tokenStack.length === 0) { 
        suggestion = generateSuggestion(input, i); 
        if (suggestion !== null) 
         suggestions.push(suggestion); 
       } 
      } 
      else 
       throw 'bracket mismatch'; 
      break; 
     default: 
      if (tokenStack.length === 0) { 
       suggestion = generateSuggestion(input, i); 
       if (suggestion !== null) 
        suggestions.push(suggestion); 
      } 
      break; 
     } 
    } 
    return suggestions; 
} 

var generateSuggestion = function(input, index) { 
    if (input[index].match(/[a-zA-Z\-\ \.:]/) !== null) 
     return { 
      'regex': input.slice(0, index) + '$', 
      'suggestion': input[index] 
     }; 
    else 
     return null; 
} 

Вот пример ввода и вывода parser()

parser('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/'); 
// output: 
[ { regex: '^[0-9]{4}$', suggestion: '-' }, 
    { regex: '^[0-9]{4}-[0-9]{1,2}$', suggestion: '-' } ] 

Таким образом, на каждом keyup вам нужно проверить список RegExp, порожденную parser, и если какой-либо из него соответствует вход затем использовать предложение.

EDIT:

Отредактировано generateSuggestion, чтобы соответствовать только полное выражение. Вот пример скрипка: http://jsfiddle.net/a7kkL6xu/6/

С забой проигнорировано: http://jsfiddle.net/a7kkL6xu/7/

+0

Я ценю это, но попробуйте ввести 20170908 – tika

+0

Да, поскольку регулярное выражение позволяет несколько цифр в течение месяца, скрипты дают «-» после ввода первой цифры. Здесь нам нужно немного изменить код. Попробуйте передать '/^[0-9] {4} - [0-9] {2} - [0-9] {2} $ /' в парсер при создании предложений. –

+0

@tika: Я немного изменил 'generateSuggestion' так, чтобы он соответствовал целым выражениям. Теперь вложение значений, таких как 20170908, не будет проблемой. Попробуйте новую скрипку: http: // jsfiddle.net/a7kkL6xu/6/ –

1

It можно только добавить символ, если это единственный возможный выбор в эта точка. Примером может служить регулярное выражение для формата YYYY-MM-DD HH24:mm: -, : и (пробел). Вот соответствующее регулярное выражение (/ пропущено, чтобы сделать его более удобным для чтения, он строже, чем в вопросе, какие-то незаконные даты еще можно как 31 февраля):

^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]) (?:[01][0-9]|2[0-3]):[0-5][0-9]$ 

Для фиксированной длины входов вы может использовать @ DineshDevkota's решение, чтобы добавить литералы и проверить весь текст с регулярным выражением. Я думаю, что это самое простое и простое решение. Вы также можете записать год, месяц и день, чтобы проверить день математически. Также правила, такие как «дата не в будущем» или «максимум 100 лет назад», могут быть разрешены только в JS, а не только с регулярным выражением.

Единственные дополнительные шаблоны, которые приходят на ум, когда персонаж может быть автоматически добавлен:

  1. A + после буквальным, например, на A+ Добавить A
  2. Минимальные входы в общем, например. на (?:foo){2,5} добавить foofoo, чтобы не путать с [fo]{2,5}, где никакие символы не могут быть добавлены
  3. Литералы после максимальной длины переменной части, например. на (?:foo){1,3}bar добавить bar после текста foofoofoo перед ставкой невозможно.
  4. Добавить остатки, например. foo|bar добавить ar, когда b был напечатан и oo, когда f был напечатан (также возможно в шаблоне, показанном в 3.), но это не будет работать для ^[a-z]+?(?:foo|bar)$, потому что мы не знаем, когда пользователь планирует закончить текст, и он может получить действительно сложный (foo|flo|flu|food|fish только sh можно добавить после fi).

Как видно из 3. и 4., дополнительные случаи, когда символы могут быть добавлены, очень ограничены, как только появятся части с переменной длиной. Вам придется анализировать регулярное выражение, разделять его в буквальном и регулярном выражении. Затем вам нужно проанализировать/проанализировать детали регулярных выражений, чтобы включить дополнительные случаи, упомянутые выше, в которые можно добавить символы. На самом деле не стоит того, чтобы спросить меня. (В вашем шаблоне телефона не может быть добавлен ни один символ.)

2

Это можно сделать с помощью одного регулярного выражения.
Для этого требуется MM: DD и HH: MM - 2 цифры, а YYYY - 4 цифры на
полностью действительная запись, но соответствует всем частичным.

Это может быть сделано для обеспечения однозначной достоверности упомянутого 2-значного значения.
Но это сделает преждевременные предложения на - - [ ] : формуляра.
Если вы хотите не вводить предложение, то 1 или 2 цифры в порядке.

JavaScript не допускает утверждений lookbehind, поэтому частичные выражения полей
ниже допустимых выражений полей в соответствующих группах.

В основном то, что происходит, это вход переписан на каждом событии пресса.
Все, что вы делаете, соответствует текущему входу в обработчике событий.

Без предложений вы просто пишете ввод со всем совпадением (группа 0).

Соотношение (группа 0) будет содержать только действительное частичное или полное совпадение.

Допустимы завершенные группы захвата поля являются 1 по 5
[год, месяц, день, часы, минуты]

Неполные поле захватывает являются группы с 6 по 10
[минут, часов, День, месяц, год]

Это логика:

// Note 1 - can handle control chars by just returning. 
// Note 2 - can avoid rewrite by keeping a global of last good, 
//   then return if current == last. 

if (last char of group 0 is a dash '-' or space ' ' or colon ':' 
    or any of groups 6 - 10 matched 
    or group 5 matched) 
    set input equal to the group 0 string; 

else if (group 4 matched) // Hours 
    set input equal to group 0 string + ':'; 

else if (group 3 matched) // Day 
    set input equal to group 0 string + ' '; 

else if (group 1 or 2 matched) // Year or Month 
    set input equal to group 0 string + '-'; 

else // Here, effectively strips bad chars from input box 
     // before they are displayed. 
    set input equal to group 0 string; 

Обратите внимание, что если группа не соответствует его значение будет NULL
и проверить всю действительность, не должно быть никаких обертоны и
группы 1 - 3 должны быть полными для всего YYYY-MM-DD или 1 - 5 с дополнительным
времени HH: MM

Final Примечание: Это анализатор, и эффективно тест на внешний вид, то есть. мерцание, переписывание в реальном времени.
Если все идет хорошо, логика в обработчике может включать проверку дня (и переписывание) в зависимости от месяца.
Кроме того, помещение может быть расширено до любого типа ввода, любого типа формы и
формы разделителей и т. Д.
Если это сработает, вы можете построить библиотеку.

# /^(?:(19\d{2}|20[0-1]\d|202[0-5])(?:-(?:(0[1-9]|1[0-2])(?:-(?:(0[1-9]|[1-2]\d|3[0-1])(?:[ ](?:(0\d|1\d|2[0-3])(?::(?:(0\d|[1-5][0-9])|([0-5]))?)?|([0-2]))?)?|([0-3]))?)?|([01]))?)?|(19\d?|20[0-2]?|[12]))/ 


^        # BOL 
(?: 
     (       # (1 start), Year 1900 - 2025 
      19 \d{2} 
     | 20 [0-1] \d 
     | 202 [0-5] 
    )        # (1 end) 
     (?: 
      -        # - 
      (?: 
       (       # (2 start), Month 00 - 12 
        0 [1-9] 
        | 1 [0-2] 
       )        # (2 end) 
       (?: 
        -        # - 
        (?: 
          (       # (3 start), Day 00 - 31 
           0 [1-9] 
          | [1-2] \d 
          | 3 [0-1] 
         )        # (3 end) 
          (?: 
           [ ]       # space 
           (?: 
            (       # (4 start), Hour 00 - 23 
             0 \d 
             | 1 \d 
             | 2 [0-3] 
            )        # (4 end) 
            (?: 
             :        # : 
             (?: 
               (       # (5 start), Minutes 00 - 59 
                0 \d 
               | [1-5] [0-9]            
              )        # (5 end) 
              | 
               ([0-5])      # (6) 
             )? 
            )? 
           | 
            ([0-2])      # (7) 
           )? 
         )? 
         | 
          ([0-3])      # (8) 
        )? 
       )? 
      | 
       ([01])      # (9) 

      )? 
    )? 
    | 
     (       # (10 start) 
      19 \d? 
     | 
      20 [0-2]? 
     | 
      [12] 
    )        # (10 end) 
) 
Смежные вопросы