我正在编写一个允许用户指定正则表达式的应用。当然,用户会犯错误,因此我需要一种方法来处理不可解析的正则表达式,并为用户提供有关如何解决问题的可操作建议。
我遇到的问题是new RegExp("something awful")
引发的异常对regex n00bs没有帮助,并且每个浏览器都有不同的消息。例如:
假设:
try{
new RegExp("(pie");
}catch(e){
console.log(e.message);
}
如果这些消息字符串是用户语言本地化的,或者随着时间的推移它们已经漂移,这对我来说并不会让我感到惊讶,这使得这是一个疯狂的结,可以解决exception.message。
我的目标是捕捉异常,弄清楚它的真正含义,并提出一个更适合初学者的消息。 (最后突出显示了无与伦比的paren,在这个例子中。)
我应该使用其他一些异常标识符吗?有没有更好的方法来分辨这些?如果没有完成所有这些,有没有人只是收集了几个最流行的浏览器中所有这些字符串的内容?
答案 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
尝试在不同的浏览器中运行此脚本,分析导致错误的模式,然后从那里开始编写工具。
修改强>
好吧,因为我担心这在开箱即用的其他浏览器中不起作用,因为它们将实际消息存储在异常对象内的其他位置。但从你的问题来看,你似乎已经想到了,从哪里获取每个浏览器的消息,所以你需要做的改变应该是次要的,我希望。