Javascript 自定义规则解析器

Javascript 自定义规则解析器,javascript,parsing,Javascript,Parsing,我有一套面具 面具看起来像这样 '09{2,9}n(6)' //读作09 //[介于2和9之间的数字] //[随机数][重复表达6次] ‘029n(7,10)’ //读作029 //[随机数][重复表达7到10次] '029n(2,5){8,15}(7,10)n' //读作029 //[一个随机数][重复表达2到5次] //[8到15之间的随机数][重复表达7到10次] //[随机数] 例如,支出3的计算结果为 '029n(4){4,9}(7)n' '029nnnn{4,9}{4,9}{4,9}

我有一套面具

面具看起来像这样

'09{2,9}n(6)' //读作09
//[介于2和9之间的数字]
//[随机数][重复表达6次]

‘029n(7,10)’
//读作029
//[随机数][重复表达7到10次]

'029n(2,5){8,15}(7,10)n'
//读作029
//[一个随机数][重复表达2到5次]
//[8到15之间的随机数][重复表达7到10次]
//[随机数]

例如,支出3的计算结果为
'029n(4){4,9}(7)n'
'029nnnn{4,9}{4,9}{4,9}{4,9}{4,9}{4,9}{n
'029nnnn{5}{9}{4}{8}{5}{9}{9}n
“029nnnn5948599n”
‘029023559485999’

我需要用javascript编写一个解析器,它可以根据这些规则生成字符串。 请注意,这不是验证,而是字符串生成


最好的方法是什么?

尝试自定义解析器。用作

var generator = new PatternGenerator('09{2,9}n(6)');
generator.generate(); // 096555555
generator.generate(); // 095000000
看看这个

和构造函数

function PatternGenerator(pattern) {
    var tokens = null;

    this.generate = function() {
        var stack = [];
        tokens = pattern.split('');

        // Read each token and add
        while (tokens.length) {
            var token = lookahead();
            if (isDigit(token)) {
                stack.push(consumeNumber());
            }
            else if (token == "n") {
                stack.push(consumeVariableNumber());
            }
            else if (token == "(") {
                var topObject = stack.pop();
                stack.push(consumeRepetition(topObject));
            }
            else if (token == "{") {
                stack.push(consumeVariableRangeNumber());
            }
            else {
                throw new Error("Invalid input");
            }
        }
        return stack.join('');
    }

    // [0-9]+
    function consumeNumber() {
        var number = "";
        while (isDigit(lookahead())) {
            number += consume();
        }
        return number;
    }

    // "n"
    function VariableNumber() {
        var number = generateRandomNumber();

        this.toString = function() {
            return Number(number);
        };
    }

    function consumeVariableNumber() {
        consume();
        return new VariableNumber();
    }

    // {x, y}
    function VariableRangeNumber(start, end) {
        var number = generateRandomNumberBetween(start, end);

        this.toString = function() {
            return Number(number);
        };
    }

    function consumeVariableRangeNumber() {
        consume(); // {
        var firstNumber = consumeNumber();
        consume(); // ,
        var secondNumber = consumeNumber();
        consume(); // }
        return new VariableRangeNumber(firstNumber, secondNumber);
    }

    // <expression>(x)
    function Repeat(object, times) {
        this.toString = function() {
            var string = "";
            for (var i = 0; i < times; i++) {
                string += object;
            }
            return string;
        };
    }

    // <expression>(x, y)
    function RepeatWithRange(object, start, end) {
        var times = generateRandomNumberBetween(start, end);

        this.toString = function() {
            return new Repeat(object, times).toString();
        };
    }

    function consumeRepetition(object) {
        consume(); // (
        var firstNumber, secondNumber;
        var firstNumber = consumeNumber();
        if (lookahead() == ",") {
            consume(); // ,
            secondNumber = consumeNumber();
        }
        consume(); // )

        if (typeof secondNumber == 'undefined') {
            return new Repeat(objectToRepeat, firstNumber);
        }
        else {
            return new RepeatWithRange(object, firstNumber, secondNumber);
        }
    }

    // Helpers to generate random integers
    function generateRandomNumber() {
        var MAX = Math.pow(2, 52);
        return generateRandomNumberBetween(0, MAX);
    }

    function generateRandomNumberBetween(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function lookahead() {
        return tokens[0];
    }

    function consume() {
        return tokens.shift();
    }

    function isDigit(character) {
        return /\d/.test(character);
    }
}
函数模式生成器(模式){
var-tokens=null;
this.generate=函数(){
var堆栈=[];
标记=模式分割(“”);
//读取每个令牌并添加
while(tokens.length){
var-token=lookahead();
if(isDigit(令牌)){
stack.push(consumernumber());
}
else if(标记=“n”){
stack.push(consumerVariableNumber());
}
else if(标记=“(”){
var toobject=stack.pop();
stack.push(使用重复(toObject));
}
else if(标记==“{”){
stack.push(consumerVariableRangeNumber());
}
否则{
抛出新错误(“无效输入”);
}
}
返回stack.join(“”);
}
// [0-9]+
函数编号(){
var数=”;
while(isDigit(lookahead())){
数字+=消耗();
}
返回号码;
}
//“n”
函数variablenNumber(){
var number=generateRandomNumber();
this.toString=函数(){
返回编号(编号);
};
}
函数consumerVariableNumber(){
消费();
返回新的变量编号();
}
//{x,y}
函数变量RangeNumber(开始、结束){
var编号=之间的GeneratorDomainNumber(开始、结束);
this.toString=函数(){
返回编号(编号);
};
}
函数consumerVariableRangeNumber(){
消费();//{
var firstNumber=consumernumber();
消费();/,
var secondNumber=consumernumber();
消费();//}
返回新的VariableRangeNumber(firstNumber,secondNumber);
}
//(十)
函数重复(对象、次数){
this.toString=函数(){
var字符串=”;
对于(变量i=0;i<次;i++){
字符串+=对象;
}
返回字符串;
};
}
//(x,y)
函数RepeatWithRange(对象、开始、结束){
var时间=之间的GeneratorDomainNumber(开始、结束);
this.toString=函数(){
返回新的Repeat(对象,时间).toString();
};
}
函数(对象){
消费();//(
变量firstNumber,secondNumber;
var firstNumber=consumernumber();
如果(lookahead()==“,”){
消费();/,
secondNumber=consumernumber();
}
消费();/)
if(typeof secondNumber==‘未定义’){
返回新的Repeat(objectToRepeat,firstNumber);
}
否则{
返回新的RepeatWithRange(对象、第一个编号、第二个编号);
}
}
//生成随机整数的助手
函数生成器域编号(){
var MAX=数学功率(2,52);
返回之间的GeneratorDomainNumber(0,最大值);
}
函数生成器域号介于两者之间(最小值、最大值){
返回Math.floor(Math.random()*(max-min+1))+min;
}
函数lookahead(){
返回令牌[0];
}
函数消耗(){
返回tokens.shift();
}
函数isDigit(字符){
return/\d/.test(字符);
}
}

我想第一步可以找到所有的
(1,10)/(5)
,并将它们后面的表达式扩展x倍?下一步是找到所有
{1,8}
,然后用1到8之间的数字替换它们?最后用一个随机数字替换所有的
n
。现在我只需要想一想怎么做…@Hailwood-在例3中,重复的部分是什么-是前面的表达式还是前面的所有内容?