我们使用Stack Overflow上的优秀validator plugin for jQuery在输入提交到服务器之前对输入进行客户端验证。
它通常效果很好,然而,这个让我们摸不着头脑。
以下验证方法用于用户名字段的提问/答案表单(请注意,您必须已注销才能在实际网站上查看此字段;它位于每个{{1页面和/question
页面)
/ask
现在这个正则表达式看起来很奇怪,但它非常简单:
是的,我们遇到了Internationalized Regular Expressions问题。 JavaScript对“单词字符”的定义根本不包括国际字符。
这是一个奇怪的部分:尽管我们已经麻烦地手动将大量有效的国际字符添加到正则表达式,但它不起作用。如果没有获取..
,则无法在用户名的输入框中输入这些国际字符只能包含A-Z,0-9,空格和连字符
..验证返回!
显然验证 正在为正则表达式的其他部分工作 ..所以...给出了什么?
另一个奇怪的部分是,此验证在浏览器的JavaScript控制台中有效,但在作为我们的标准* .js包含的一部分执行时则不行。
/ ^ [\ W- \sÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜäëïöüçÇßØøÅåÆæÞþÐð] + $ / .test('ÓBilldehÓra')=== true
我们之前在JavaScript代码中遇到过一些非常奇怪的国际角色问题,导致一些非常非常讨厌的黑客攻击。我们想了解这里发生了什么,为什么。请指教!
答案 0 :(得分:36)
我认为电子邮件和网址验证方法在这里是一个很好的参考,例如。电子邮件方法:
email: function(value, element) {
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
},
The script to compile that regex
换句话说,用这个替换你的“疯狂月亮”字符的任意列表可能会有所帮助:
[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]
基本上,这可以通过用更一般的定义替换needs-encoding字符来避免您在其他地方遇到的字符编码问题。虽然不一定更具可读性,但到目前为止它比您的完整列表更短。
答案 1 :(得分:13)
这不是一个真正的答案,但我还没有50个代表添加评论......它肯定会归因于编码问题。
是的“ECMA不应该关心编码......”等等等等,如果你使用的是Firefox,请转到查看>字符编码>西方(ISO-8859-1)然后尝试使用名称字段。
手动更改编码后,它对我来说很好(授予页面的其余部分不喜欢编码开关,:P)
(在IE8上,您可以转到页面>编码>西欧(Windows)以获得相同的效果)
答案 2 :(得分:3)
JS文件的字符编码是什么?
对于XML QNames,我使用此RegExp:
/**
* Definition of an XML Name
*/
var NameStartChar = "A-Za-z:_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D"+
"\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF"+
"\uF900-\uFDCF\uFDF0-\uFFFD\u010000-\u0EFFFF";
var NameChar = NameStartChar+"\\-\\.0-9\u00B7\u0300-\u036F\u203F-\u2040";
var Name = "^["+NameStartChar+"]["+NameChar+"]*$";
RegExp (Name).test (value);
它的魅力与国际化角色一样。注意逃避。因为我能够将JS文件限制为 ASCII 字符。因此,在处理ISO-8859与UTF-8字符集时,我不会遇到麻烦。
如果您使用ASCII不是真正子集的字符编码(例如,在亚洲UTF-16中),则情况不再如此。
干杯,
答案 3 :(得分:2)
列出的国际字符是扩展ASCII的一部分。你添加的那些肯定不是。
答案 4 :(得分:2)
看到该语句在控制台中有效,是否必须按照.js文件的保存方式(即ascii或UTF-8)进行操作,并且浏览器正在加载它们并在此过程中转换字符? / p>
答案 5 :(得分:2)
使用类似Fiddler或Charles(不是Firebug的Net面板,或其他任何实际位于浏览器中的内容)来检查实际传输的内容。这几乎可以肯定是一个编码问题:文件已保存在某些Microsoft字符集中,并以UTF-8格式发送,或者反过来。
对于JS RegExps,您可以像Boldewyn所指出的那样,通过为所需字符指定超出US-ASCII范围的Unicode代码点来避免这些问题。不过,确保你不会在保存文件的地方和服务地点之间混合编码也是一样。
答案 6 :(得分:2)
这里游戏的后期,但我只是使用了这个表达式,它似乎对我有用。似乎相当全面且相对简单:
var re = /^[A-zÀ-ÿ\s\d-]*$/g;
var str1 = 'casa-me,pois 99 estou farto! Eis a lista:uma;duas;três';
var str2 = 'casa-me pois 99 estou farto Eis a lista uma duas três';
alert(re.test(str1));
alert(re.test(str2));