区分JavaScript中的正则表达式解析异常

区分JavaScript中的正则表达式解析异常,javascript,regex,Javascript,Regex,我正在编写一个允许用户指定正则表达式的应用程序。当然,用户也会犯错,所以我需要一种处理无法解析的正则表达式的方法,并就如何解决问题向用户提供一些可行的建议 我遇到的问题是,newregexp(“糟糕的东西”)引发的异常对regexn00b没有帮助,每个浏览器都有不同的消息。例如: 鉴于: try{ new RegExp("(pie"); }catch(e){ console.log(e.message); } Firefox抛出“未终止的插入语” Safari抛出“失踪”)

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

我遇到的问题是,
newregexp(“糟糕的东西”)
引发的异常对regexn00b没有帮助,每个浏览器都有不同的消息。例如:

鉴于:

try{
    new RegExp("(pie");
}catch(e){
    console.log(e.message);
}
  • Firefox抛出“未终止的插入语”
  • Safari抛出“失踪”)
  • Chrome抛出“未终止组”
如果这些消息字符串是用户语言本地化的,或者它们随着时间的推移而漂移,这就不会让我感到惊讶了,这使得用exception.message解开这个疯狂的结

我的目标是捕捉异常,找出它的真正含义,并发布一条对初学者更友好的信息。(在本例中,最后突出显示不匹配的paren。)


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

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

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本机错误消息的其他解决方案也无法正常工作


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

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

此文件具有正则表达式的YACC语法:;与JISON一起使用它可能不太难


PERL正则表达式的BNF语法:

根据我的评论,我已经拼凑了一个小脚本来“获取”可能的错误消息和导致它们的模式

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

其思想是:您有一个工作正则表达式,它使用尽可能多的正则表达式特性。然后随机地对它进行变异(添加、删除或交换字符)并尝试编译它。您可以这样做几千次,并收集所有错误消息。希望chance比我们任何人都更擅长找出可能的畸形模式

您肯定应该改进基本模式,包括JavaScript提供的所有regex特性,并在替换表中包括所有元字符。但除此之外,我似乎始终会收到6条可能的错误消息:

Unterminated group
Invalid group    
Nothing to repeat
Unmatched ')'
Unterminated character class
\ at end of pattern
尝试在不同的浏览器中运行此脚本,分析导致错误的模式,然后您就可以编写工具了

编辑:


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

我想看看一些流行的regex在线测试页面做了什么regex
(abcd})
大括号太少还是太多?这里有一个技巧可以帮助您掌握最可能的消息。编写一个包含一些有效但非常复杂的正则表达式的脚本。真正使用和滥用JavaScript中所有可用的正则表达式功能。当然还有筑巢。然后随机删除、添加或更改其中的一些字符,并尝试编译它们。并保存您收到的所有错误消息(以及导致错误的正则表达式)。由于随机性,你应该能够尝试很多失败的案例,而且由于自动化,你不必担心重复。这真的很聪明,而且感谢你偷看Opera(我的列表中甚至没有尝试过)。该应用程序甚至已经有了一个服务器端Node.js组件,您是对的,等待往返并从服务器获得优秀的建议可能更有意义,而不是立即从客户端获得平庸的建议。