7

我正在编写一个允许用户指定正则表达式的应用程序。当然,用户会犯错误,所以我需要一种方法来处理无法解析的正则表达式,并就如何解决问题给用户一些可行的建议。

我遇到的问题是抛出的异常new RegExp("something awful")对正则表达式 n00bs 没有帮助,并且每个浏览器都有不同的消息。例如:

鉴于:

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

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

我的目标是捕捉异常,弄清楚它的真正含义,并提出对初学者更友好的信息。(在本例中,最终突出显示不匹配的括号。)

我应该使用其他一些异常标识符吗?有没有更好的方法来区分这些?如果这一切都失败了,是否有人刚刚收集了几个最流行的浏览器中的所有这些字符串?

4

3 回答 3

3

想法:在运行时把它全部弄清楚。例如

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 原生错误消息的解决方案也不会。

我建议将正则表达式发送到运行 node.js 的应用程序并获得漂亮的 V8 错误消息 :)

于 2012-11-29T21:37:04.993 回答
1

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

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

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

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

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

尝试在不同的浏览器中运行这个脚本,分析导致错误的模式,然后你应该能够编写你的工具。

编辑:

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

于 2012-11-29T22:05:58.670 回答
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

于 2012-11-29T21:46:41.220 回答