2016-10-20 2 views
0

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

character set: abcd 
character format: ??j? (question mark represents a a character from character set) 

Пример

abjd = match 
bdja = match 
dbja = match 
ab = no match 
aajd = no match 
abjdd = no match 
abj = no match 

Я создал регулярок строитель (в JS) следующим образом:

// characters are the character set 
// wordFormat is the character format 
// replace(str, search, replacement) replaces search in str with replacement 
var chars = "[" + characters + "]{1}"; 
var afterSpecialConversion = replace(wordFormat, "?", chars); 

var myRegex = new RegExp("^" + afterSpecialConversion + "$", "gi"); 

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

Также предоставляется набор символов aabcda может существовать в два раза. Какие-либо предложения?

ответ

1

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

Я предоставил example regex on Regex101 для демонстрации в вашем вопросе.

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

(?:([<chars>])(?!.*\<m>)){<n>} 

Где <chars> установлен символ, который вы хотите использовать, m является индексом множества вопросительные знаки (начиная с 1 - более на это мгновенно), а <n> - количество вопросительных знаков в группе. Это дает регулярное выражение-строитель код, который выглядит следующим образом:

function getRe(pattern, chars) { 
    var re = "^"; 
    var qMarkGroup = 1; 
    var qMarkCount = 0; 

    for (var index in pattern) { 
     var char = pattern[index]; 
     if (char === "?") { 
      qMarkCount += 1; 
     } else { 
      if (qMarkCount > 0) { 
       re += "(?:([" + chars + "])(?!.*\\" + qMarkGroup + ")){" + qMarkCount + "}" + char; 
       qMarkCount = 0; 
       qMarkGroup += 1; 
      } 
     } 
    } 

    // Need to do this again in case we have a group of question marks at the end of the pattern 
    if (qMarkCount > 0) { 
     re += "(?:([" + chars + "])(?!.*\\" + qMarkGroup + ")){" + qMarkCount + "}"; 
    } 
    re += "$"; 
    return new Regexp(re, "gi"); 
} 

Code demo on Repl.it

Очевидно, что это определение функции очень многословным, чтобы продемонстрировать принципы, связанные. Не стесняйтесь играть в гольф (но помните, чтобы следить за проблемами забора, как я описал в комментариях).

Кроме того, не забудьте очистить входы. Это пример и сломается, если кто-то, например, помещает ] в chars.