2015-09-15 4 views
-1

Есть ли какой-либо путь или любая библиотека, которая может вычислить JS RegEx из набора строк, которые я хочу сопоставить?Генерировать JS Regex из набора строк

К примеру, у меня есть набор строк:

  • abc123
  • abc212

и генерировать abc\d\d\d?

Или этот набор:

  • aba111
  • abb111
  • abc

и генерировать ab.?

Обратите внимание, что я не нужен очень точный RegEx, я просто хочу один, который может сделать строки, . и .*

+0

Почему 'а \ d \ d \ d' и не' а (?: 123 | 212) '? – Mariano

+0

Проверьте [text2re] (http://www.txt2re.com/), как предложено в http://stackoverflow.com/questions/6219790/need-a-regex-tool-that-suggests-expressions-based-on- selected-text – Mariano

ответ

2

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

abc[0-9][0-9][0-9] 
abc[1-2][0-5][2-3] 
abc[1-2][0-5][2-3]a* 
abc\d* 
abc\d+ 
abc\d+a*b*c* 
... 

И так далее. При этом вы можете найти грамматику a, которая соответствует установленным условиям. Один из способов - просто скопировать сходства и различия в каждом элементе ввода. Таким образом, чтобы сделать это с помощью второго примера:

  • aba111
  • abb111
  • абв

ab часть одинакова для всех из них, поэтому мы начнем с ab как регулярное выражение. Тогда следующий символ может быть a, b or c, поэтому мы можем сказать (a|b|c). Затем 1 or empty три раза. Это приведет к:

ab(a|b|c)(1|)(1|)(1|) 

Это правильное регулярное выражение, но, возможно, не тот, который вы хотели.

+0

'ab (a | b | c) (1 |) (1 |) (1 |)' соответствует '' abc11' ', не входит в список :) – Mariano

+0

@Mariano Точка должна соответствовать элементам в наборе (не для их соответствия и только для них), это не имеет большого значения, если это происходит с другими вещами. Строка '' aba11 "' является подстрокой '' aba111 "', поэтому не удивительно, что она также соответствует. Это просто происходит из-за подхода, о котором я упомянул, поскольку это делается персонажем по характеру. –

+0

Я уточнил вопрос, мне не нужна слишком большая сложность. –

0

Может быть, это слишком просто, но вы можете использовать это,

var arr = ['abc121','abc212','cem23']; 
var regex_arr = []; 

arr.sort(function(a, b){return -a.length+b.length;}); 
for(var i in arr[0]){ 
    for(var j in arr){ 
     if(i>=arr[j].length){ 
      regex_arr[i] = {value:'',reg:'*',use_self:false}; 
     }else{ 
      var c = arr[j][i]; 
      var current_r = '.'; 

      if(isNaN(c)){ 
       if(/^[A-Za-z]$/.test(c)){ 
        current_r = '\\w'; 
       }else{ 
        current_r = '\\W'; 
       } 
       //... may be more control 
      }else{ 
       current_r = '\\d'; 
      } 
      if(!regex_arr[i]){ 
       regex_arr[i] = {value:c,reg:current_r,use_self:true}; 
      }else{ 
       if(regex_arr[i].value!=c){ 
        if(regex_arr[i].reg!=current_r){ 
         regex_arr[i].reg = '.'; 
        } 
        regex_arr[i].use_self = false; 
        regex_arr[i].value = c; 
       } 
      } 
     } 
    } 
} 
var result = ''; 
for(var i in regex_arr){ 
    if(regex_arr[i].use_self){ 
     result += regex_arr[i].value; 
    }else{ 
     result += regex_arr[i].reg; 
    } 
    if(regex_arr[i].reg=='*'){ 
     break; 
    } 
} 
console.log("regex = "+result); 
for(var i in arr){ 
    var r = new RegExp(result); 
    console.log(arr[i] + ' = '+r.test(arr[i])); 
} 

Результаты

regex = \w\w\w\d\d* 
abc121 = true 
abc212 = true 
cem23 = true 
+0

Нет, это не сработает. –

+0

https://jsfiddle.net/vs311f5h/ –

Смежные вопросы