在JavaScript中讲述正则表达式解析异常

时间:2012-11-29 21:25:03

标签: javascript regex

我正在编写一个允许用户指定正则表达式的应用。当然,用户会犯错误,因此我需要一种方法来处理不可解析的正则表达式,并为用户提供有关如何解决问题的可操作建议。

我遇到的问题是new RegExp("something awful")引发的异常对regex n00bs没有帮助,并且每个浏览器都有不同的消息。例如:

假设:

try{
    new RegExp("(pie");
}catch(e){
    console.log(e.message);
}
  • Firefox抛出“未终止的括号”。
  • Safari抛出“失踪”“
  • Chrome会抛出“未终止的群组”

如果这些消息字符串是用户语言本地化的,或者随着时间的推移它们已经漂移,这对我来说并不会让我感到惊讶,这使得这是一个疯狂的结,可以解决exception.message。

我的目标是捕捉异常,弄清楚它的真正含义,并提出一个更适合初学者的消息。 (最后突出显示了无与伦比的paren,在这个例子中。)

我应该使用其他一些异常标识符吗?有没有更好的方法来分辨这些?如果没有完成所有这些,有没有人只是收集了几个最流行的浏览器中所有这些字符串的内容?

3 个答案:

答案 0 :(得分:3)

想法:在运行时全部计算出来。 E.g。

var tellMeWhatIDidWrong = (function() {

    var tests = {
        '(': 'You did not close your group... duh!',
        ')': 'You seem to have an unmatched parenthesis.',
        '*': 'That token is illegal in that position'
    };

    var errors = {};

    for (var i in tests) {
        try { RegExp(i); } catch(e) { 
            errors[String(e).split(':').pop()] = tests[i];
        }
    }


    return function(regexStr) {
        try { RegExp(regexStr); } catch(e) {
            e = String(e).split(':').pop();
            if (e in errors) {
                return errors[e];
            }
            return 'Unknown error';
        }
        return 'Nothing -- it is fine!';
    };

}());

tellMeWhatIDidWrong('(abc?'); // -> "You did not close your group... duh!"

当然,只有当浏览器的内置错误报告足够具体时,这才能正常工作。他们中的许多人都很糟糕。例如。 Opera完全没有提示该问题,因此上述方法不会很好,并且任何其他解决方案都不会依赖Opera的本机错误消息。

我建议将regexps发送到运行node.js的应用程序并获取不错的V8错误消息:)

答案 1 :(得分:1)

使用PEG.js或JISON创建正则表达式解析器。您将能够获得具体且一致的错误。

此文件具有正则表达式的YACC语法:http://swtch.com/usr/local/plan9/src/cmd/grep/grep.y;使用JISON可能并不太难。

PERL正则表达式的BNF语法:http://www.cs.sfu.ca/~cameron/Teaching/384/99-3/regexp-plg.html

答案 2 :(得分:1)

根据我的评论,我在一起编写了一个小脚本来“收集”可能的错误消息和导致它们的模式。

JSFiddle(仅在Chrome上试过,我希望RegExp异常对象具有与其他浏览器相同的结构

这个想法是这样的:你有一个工作正则表达式,它使用尽可能多的正则表达式功能。然后你随机改变它(添加,删除或交换字符)并尝试编译它。您可以执行此操作几千次,并收集所有错误消息。希望机会能够提出比我们任何人都更糟糕的模式。

您绝对应该改进基本模式,包括JavaScript提供的所有正则表达式功能,并在替换表中包含所有元字符。但除此之外,我似乎总是得到6条可能的错误消息:

Unterminated group
Invalid group    
Nothing to repeat
Unmatched ')'
Unterminated character class
\ at end of pattern

尝试在不同的浏览器中运行此脚本,分析导致错误的模式,然后从那里开始编写工具。

修改

好吧,因为我担心这在开箱即用的其他浏览器中不起作用,因为它们将实际消息存储在异常对象内的其他位置。但从你的问题来看,你似乎已经想到了,从哪里获取每个浏览器的消息,所以你需要做的改变应该是次要的,我希望。