为什么不能在Regexes中定义自己的自定义charclasses?

时间:2012-10-07 09:49:33

标签: javascript regex pcre

我的意思是,而不是

/^[asdfjkl;]foo[asdfjkl;]bar[asdfjkl;]baz$/i

甚至

RegExp('^[[:HOMEROW:]]foo[[:HOMEROW:]]bar[[:HOMEROW:]]baz$'.replace(/\[:HOMEROW:]/g, 'asdfjkl;'))

我可能只能写:

/\H=[asdfjkl;];^\Hfoo\Hbar\Hbaz$/

没有人想到这一点,并假设他们有,为什么它不享受更多支持或实施?

注意:我对此的哲学方面更感兴趣:排除该功能的理由是什么?

2 个答案:

答案 0 :(得分:2)

您可以为RegExp创建一个包装器对象:

myRegExp = function(regex,mods) {
    var customclasses = {
        nonDotLocalChar:'A-Za-z0-9!#$%&\'*+-/=?^_`{|}~'
    }, i;
    for( i in customclasses) {
        regex = regex.replace(new RegExp("\[:(\^?)"+i+":\]","i"),"$1"+customclasses[i]);
    }
    return new RegExp(regex,mods);
};

然后您可以使用以上内容:

var eam = new myRegExp("^[[:nondotlocalchar:]](?(?:[[:nondotlocalchar:]].........");

您也可以使用它:

new myRegExp("[[:^nondotlocalchar:]]"); // negates the custom class
new myRegExp("[@[:nondotlocalchar:]]"); // allow anything from the custom class, or the @ character

答案 1 :(得分:1)

既然你提出了一个哲学问题(这对于像SO这样的网站来说不是很好的问题),那么让我试着给出一个相当推测的答案。毕竟,我不能代表语言设计师,但我可以猜到:

通常,当一个正则表达式变得像这样可怕时,它是一个可靠的信号,表明正则表达式不适合这项工作。所以在某种程度上,自定义角色类会鼓励糟糕的编程(比如尝试用正则表达式验证电子邮件地址)。我怀疑这就是为什么没有足够智能定义正则表达式标准的人选择实现这一功能。

例如,如果您的目标是查找电子邮件地址,那么最好使用基本的正则表达式进行非常基本的扫描,例如

\S+@\S+\.\S+

然后使用专用的电子邮件地址解析器查看结果,以清除/修剪不匹配。

更好的例子可能是日期验证:

可以使用正则表达式验证MM / DD / YYYY日期

^(?:(?:(?:(?:(?:0?[13578]|1[02])\/31)|(?:(?:0?[13-9]|1[0-2])\/(?:29|30)))\/(?:1[6-9]|[2-9]\d)\d{2})|(?:0?2\/29\/(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))\/(?:0?[1-9]|1\d|2[0-8])\/(?:(?:1[6-9]|[2-9]\d)\d{2}))$

但您可能应该使用像

这样的正则表达式
^\d\d/\d\d/\d\d\d\d$

并使用日期解析器在第二步中找出有效日期。