【问题标题】:Regex match character set without previous duplication没有先前重复的正则表达式匹配字符集
【发布时间】:2016-10-20 21:30:16
【问题描述】:

创建动态正则表达式以匹配一组不同的字符(运行时提供的字符及其顺序)的最佳方法是什么。

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");

不幸的是,这并没有达到结果,因为它不考虑重复项。我考虑过使用匹配组来避免重复,但是我不知道如何从集合的其余部分中否定已经存在的字符组。

还给定字符集aabcd 现在a 可以存在两次。有什么建议么?

【问题讨论】:

    标签: javascript regex text dynamic match


    【解决方案1】:

    您的正则表达式构建器方法是正确的(虽然有点可维护性混乱,所以请仔细记录它),但不够复杂。你需要做的是使用lookaheads

    我为您的问题中的演示提供了example regex on Regex101

    更一般的原则是将每组n问号替换为与此匹配的模式:

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

    &lt;chars&gt; 是您要使用的字符集,m 是问号集的索引(从 1 开始 - 稍后会详细介绍),&lt;n&gt; 是问题的数量组中的标记。这会产生如下所示的正则表达式生成器代码:

    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

    显然,这个函数定义非常冗长,以演示所涉及的原理。随意打高尔夫球(但请记住要注意我在 cmets 中描述的栅栏问题)。

    此外,请务必清理输入。这是一个示例,例如,如果有人将] 输入chars,就会中断。

    【讨论】:

      猜你喜欢
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 2016-10-24
      • 2013-06-03
      • 2023-03-09
      相关资源
      最近更新 更多