2013-07-11 2 views
2

У меня есть таблица, которая отображается с использованием данных, над каждым столбцом У меня есть пустое текстовое поле, в котором пользователи могут вводить термины для фильтрации. Это отлично работает во всех текстовых полях и работает нормально и для целочисленных полей. Я делаю некоторое преобразование для некоторых терминов, например, если пользователь вводит NULL или NOT NULL, например, я конвертирую это в regex^$ или.Преобразование числа читаемых человеческих чисел в Regex

Я знаю, что regex предназначен для поиска текстовых строк, но это то, что использует datatables, поэтому я делаю это. Я хочу, чтобы пользователи могли вводить значение, такое как «x to y», и иметь возможность преобразовать его в регулярное выражение. Я не могу найти функцию, которая делает это, если кто-нибудь знает об этом, пожалуйста, дайте мне знать.

Предполагая, что функция еще не существует, предположим, что будут найдены только положительные целые числа и говорят до 7 цифр. поэтому можно искать 0 - 9999,999. Также единственным способом запускается ключевое слово с пробелами «до».

так что-то вроде этого, чтобы начать:

function convertNumRangeRegex(s){ 

if(s.indexOf(" to ") != -1){ 
var range = s.split(" to "); 
lowRange = Number(range[0]); 
highRange = Number(range[1]); 

if(lowRange >= 0 && lowRange < 10 && highRange < 10){ 
     s = "^[" + lowRange + "-" + highRange + "]$"; 
}}; 


return s; 
}; 

Это работает с номерами 0-9, но расширение на это похоже было бы получить довольно некрасиво. Я нахожусь для любых ides. Благодарю.

+0

Если речь идет о базе данных, вы бы жир лучше обеспечить различные пути для согласования числа, согласования диапазона и т.д. Было бы получить довольно некрасиво действительно. Вместо того, чтобы возвращать регулярное выражение, возвращайте функцию обратного вызова, которая может возвращать true или false, en в зависимости от предоставленного условия поиска, что обратный вызов может использовать регулярное выражение, меньшее/большее сравнение, соответствие диапазонов и т. Д. – Wrikken

+0

только что нашел этот вопрос, который похож на http : //stackoverflow.com/questions/4101053/generate-a-regexp-from-a-numeric-range Похоже, что не рекомендуется использовать регулярное выражение для интерпретации чисел –

+0

@DavidStetler - Да, при попытке автоматического генерации этих регулярных выражений , без вопросов, с просьбой о боли. Во имя здравомыслия и порядочности просто преобразуйте строки в числа, используя 'parseInt', или что-то в этом роде. – femtoRgon

ответ

5

Проверка числа в диапазоне чисел с регулярным выражением является сложной проблемой. Эти regexs будет соответствовать число в заданном диапазоне:

\b[0-9]{1,7}\b  # 0-9999999 
\b[1-9][0-9]{2,6}\b # 100-9999999 
\b([4-9][0-9]{4}|[1-9][0-9]{5,6})\b # 40000-9999999 

Он начинает выходить из руки, когда у вас есть сложные диапазоны

\b(?:5(?:4(?:3(?:2[1-9]|[3-9][0-9])|[4-9][0-9]{2})|[5-9][0-9]{3})|[6-9][0-9]{4}|[1-9][0-9]{5}|[1-8][0-9]{6}|9(?:[0-7][0-9]{5}|8(?:[0-6][0-9]{4}|7(?:[0-5][0-9]{3}|6(?:[0-4][0-9]{2}|5(?:[0-3][0-9]|4[0-3]))))))\b # 54321-9876543

enter image description here

0

Форвард

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

Это, я уверен, у вас есть свои причины.

Объяснение

Этот набор функций будет построить регулярное выражение, которое будет сделать следующее:

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

Общий обзор

Функция funRegexRange делает всю тяжелую работу.Построив строку, которая будет соответствовать всем цифрам от 0 до UpperRange

Функции funBuildRegexForRange затем конструирует фактическое регулярное выражение с отрицательным предпросмотром и положительным предпросмотром.

В результате регулярных выражений будет проверять ваш номер находится между 0 и UpperRange включительно, а не между 0 и LowerRange не включительно.

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

Примеров

Чтобы получить регулярное выражение для диапазона от 400 до 500:

re = funBuildRegexForRange(400, 500, true) 

Установив последний параметр, чтобы верно вам это продемонстрируют различные части строятся и полное регулярное выражение.

[0-3][0-9]{2}, [0-9]{1,2} 
[0-4][0-9]{2}, 500, [0-9]{1,2} 
Full Regex = /^(?!(?:[0-3][0-9]{2}|[0-9]{1,2})$)(?=(?:[0-4][0-9]{2}|500|[0-9]{1,2})$)/ 

В результате регулярное выражение выглядит

Regular expression visualization

Просить диапазоне от 400 - 999999999999 [двенадцать цифр] возвращает этот монстр:

Full Regex = /^(?!(?:[0-3][0-9]{2}|[0-9]{1,2})$)(?=(?:[0-8][0-9]{11}|9[0-8][0-9]{10}|99[0-8][0-9]{9}|999[0-8][0-9]{8}|9999[0-8][0-9]{7}|99999[0-8][0-9]{6}|999999[0-8][0-9]{5}|9999999[0-8][0-9]{4}|99999999[0-8][0-9]{3}|999999999[0-8][0-9]{2}|9999999999[0-8][0-9]|99999999999[0-8]|999999999999|[0-9]{1,11})$)/

Javascript код

Живой пример: https://repl.it/CLd4/4

Полный код:

function funRegexRange (UpperRange, Inclusive, Debug) { 
    // this function will build a basic regex that will match a range of integers from 0 to UpperRange 

    UpperRange += "" // convert the value to a string 
    var ArrUpperRange = UpperRange.split("") 
    var intLength = ArrUpperRange.length 
    var LastNumber = ArrUpperRange[intLength] 
    var AllSubParts = [] 
    var SubPortion = "" 

    for (i = 0; i < intLength; i++) { 
     Position = intLength - (i +1) 
     if (Position >= 2) { 
      Trailing = "[0-9]{" + Position + "}"; 
     } else if (Position == 1) { 
      Trailing = "[0-9]"; 
     } else { 
      Trailing = ""; 
     } 

     if (ArrUpperRange[i] >= 2) { 
      ThisRange = "[0-" + (ArrUpperRange[i] - 1) + "]" 
     } else if (ArrUpperRange[i] == 1) { 
      ThisRange = "0" 
     } else { 
      ThisRange = "" 
     } 

     if (Debug) { 
     // console.log("Pos='" + Position + "' i='" + i + "' char='" + ArrUpperRange[i] + "' ThisRange='" + ThisRange + "' Trailing='" + Trailing + "'") 
     } 

     if (ThisRange === "" && Trailing !== "") { 
      // no need to return the this as this will be matched by the future SubPortions 
     } else { 
      if (Position === 0 && ThisRange ==="" && Trailing === "") { 
      } else { 
       AllSubParts.push(SubPortion + ThisRange + Trailing); 
     } 
     } 
    SubPortion += ArrUpperRange[i] 
    } 

    // insert the last number if this it should be included in the range 
    if (Inclusive) { 
     AllSubParts.push(UpperRange) 
    } 

    // all all numbers that have less digits than the range 
    if (intLength - 1 >= 2) { 
     Trailing = "[0-9]{1," + (intLength - 1) + "}"; 
    } else if (intLength - 1 >= 1) { 
     Trailing = "[0-9]"; 
    } else { 
     Trailing = ""; 
    } 

    // insert trailing into the output stream 
    if (Trailing){ 
     AllSubParts.push(Trailing); 
    } 

    if (Debug) { 
     console.log(AllSubParts.join(", ")); 
    } 
    return AllSubParts.join("|"); 
} // end function funRegexRange 


function funBuildRegexForRange (Start, End, Debug){ 
    var Regex = new RegExp("^(?!(?:" + funRegexRange (LowerRange, false, Debug) + ")$)(?=(?:" + funRegexRange (UpperRange, true, Debug) + ")$)" ,"") 
    if (Debug) { 
     console.log("Full Regex = " + Regex + "") 
    } 
    return Regex 
} 

var Debug = false; 
var Inclusive = true; 
var LowerRange = "400"; 
var UpperRange = "500"; 

// var re = funBuildRegexForRange(LowerRange, UpperRange, true) 

if (Debug){ 
    for (Range = 0; Range < 13; Range++) { 
     console.log ("funRegexRange ('" + Range + "', " + Inclusive +") ="); 
     funRegexRange (Range, Inclusive, Debug); 
     console.log (""); 
    } 
} 

var Regex = funBuildRegexForRange(LowerRange, UpperRange, Debug) 

for (i = 1000; i < 1020; i++) { 
    TestNumber = i + "" 
    if (TestNumber.match(Regex)) { 
     console.log(TestNumber + " TestNumber='" + TestNumber + "' matches"); 
    } else { 
//  console.log(TestNumber + " does not match '" + Regex + "'") 
    } 
} 
Смежные вопросы