js中escape、encodeURI、encodeURIComponent的区别

三个函数均可把字符串作为 URI 组件进行编码。

escape/unescape

该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ – _ + . / 。其他所有的字符都会被转义序列替换。

ECMAScript v3 反对使用该方法,应用使用 encodeURI() 和 encodeURIComponent() 替代它。

encodeURI/decodeURI

该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: – _ . ! ~ * ‘ ( ) 。

该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:;/?:@&=+$,#

如果 URI 组件中含有分隔符,比如 ? 和 #,则应当使用 encodeURIComponent() 方法分别对各组件进行编码。

encodeURIComponent/decodeURIComponent

该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: – _ . ! ~ * ‘ ( ) 。
其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。

请注意 encodeURIComponent() 函数 与 encodeURI() 函数的区别之处,前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。

正则表达式 – 元字符

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\\’ 匹配 “\” 而 “\(” 则匹配 “(“。
^ 匹配输入字符串的开始位置。如果设置了
**RegExp** 对象的
**Multiline** 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了
**RegExp** 对象的
**Multiline** 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。 * 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。
{*n*} *n* 是一个非负整数。匹配确定的 *n* 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{*n*,} *n* 是一个非负整数。至少匹配*n* 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。
{*n*,*m*} *m* 和 *n* 均为非负整数,其中*n* <= *m*。最少匹配 *n* 次且最多匹配 *m* 次。刘, “o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {*n*}, {*n*,}, {*n*,*m*}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。
. 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。
(*pattern*) 匹配*pattern* 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用
**SubMatches** 集合,在Visual Basic Scripting Edition 中则使用
**$0**…
**$9** 属性。要匹配圆括号字符,请使用 ‘\(‘ 或 ‘\)’。
(?:*pattern*) 匹配 *pattern* 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
(?=*pattern*) 正向预查,在任何匹配 *pattern* 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以 后使用。例如, ‘Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000” 中的 “Windows” ,但不能匹配 “Windows 3.1” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!*pattern*) 负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching *pattern* 的 字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1” 中的 “Windows”,但不能匹配 “Windows 2000” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
*x*|*y* 匹配 *x* 或 *y*。例如,’z|food’ 能匹配 “z” 或 “food”。'(z|f)ood’ 则匹配 “zood” 或 “food”。
[*xyz*] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^*xyz*] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。
[*a-z*] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。
[^*a-z*] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\c*x* 匹配由*x*指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 *x* 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]’。
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。
\x*n* 匹配 *n*,其中 *n* 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, ‘\x41′ 匹配 “A”。’\x041’ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。.
\*num* 匹配 *num*,其中 *num* 是一个正整数。对所获取的匹配的引用。例如,'(.)\1′ 匹配两个连续的相同字符。
\*n* 标识一个八进制转义值或一个后向引用。如果 \*n* 之前至少 *n* 个获取的子表达式,则 *n* 为后向引用。否则,如果 *n* 为八进制数字 (0-7),则 *n* 为一个八进制转义值。
\*nm* 标识一个八进制转义值或一个后向引用。如果 \*nm* 之前至少有is preceded by at least *nm* 个获取得子表达式,则 *nm* 为后向引用。如果 \*nm* 之前至少有 *n* 个获取,则 *n* 为一个后跟文字 *m *的后向引用。如果前面的条件都不满足,若  *n* 和 *m* 均为八进制数字 (0-7),则 \*nm* 将匹配八进制转义值 *nm*。
\*nml* 如果 *n* 为八进制数字 (0-3),且 *m* 和 *l* 均为八进制数字 (0-7),则匹配八进制转义值 *nml。*
\u*n* 匹配 *n*,其中 *n* 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

正则表达式 – 分组语法(捕获/断言/注释)

分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(? 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

谷歌制图服务(Google Chart)接口生成二维码

Google公布了制图服务(Google Chart)的接口,这项服务用起来相当简单,只使用浏览器就可以用来为统计数据自动生成图片。

目前谷歌制图服务提供折线图、条状图、饼图、Venn图、散点图、二维码图等。下面我们来看下如何使用这个简单的服务来生成二维码。

接口地址 http://chart.apis.google.com/chart?chs=宽高值x宽高值&cht=qr&chld=等级|边距&chl=内容

参数说明:

宽高值:生成二维码尺寸,单位是像素,目前生成的二维码都是正方形的,所以两个宽高值都设置为一样的值

等级:四个等级,L-默认:可以识别已损失的7%的数据;M-可以识别已损失15%的数据;Q-可以识别已损失25%的数据;H-可以识别已损失30%的数据

边距:生成的二维码离图片边框的距离

内容:生成二维码的内容,但一定要URLENCODE

下面给一个JS生成二维码地址的函数

function qrcode(data, size, level, margin) {
    size = size || 320;
    level = level || 'L';
    margin = margin | 0;
    return [
        'http://chart.apis.google.com/chart?cht=qr',
        '&chs='+size+'x'+size,
        '&chld='+level+'|'+margin,
        '&chl='+encodeURIComponent(data)
    ].join('');
}
//测试
var url = qrcode('http://www.anrip.com/post/748');
window.location.href = url;

JavaScript获取浏览器Flash版本

/*!
 * 获取浏览器Flash版本号
 */
function get_flash_version() {
  var SF, FV = 0, BR = window.navigator;
  if(BR.plugins && BR.mimeTypes.length) {
    SF = BR.plugins["Shockwave Flash"];
    if(SF && SF.description) {
      FV = SF.description.replace(/[^\d\.]/g,"").split(".")[0];
    }
  } else if(BR = window.ActiveXObject) {
    try {
      SF = new BR("ShockwaveFlash.ShockwaveFlash.7");
      FV = SF.GetVariable("$version").split(" ")[1].split(",")[0];
    } catch(e) {}
  }
  return +FV;
}

JavaScript根据给定的时间获取Unix时间戳

因为项目需要,今天写了一个JS版的根据给定的时间获取Unix时间戳的转换函数,不多废话,直接上代码。

/*!
 * 根据给定的时间获取Unix时间戳
 * @time : 时间;字符:'yyyy-mth-dd hh:mm:ss'
 * @tzone: 时区;整数:[-12,+12]
 */
function timestamp(time, tzone) {
  if(time) {
    var t = time.match(/((\d{4})\D(\d\d)\D(\d\d))(\s(\d\d)\D(\d\d)\D(\d\d))?/) || [];
    if(t[8]) time = new Date(t[2], t[3]-1, t[4], t[6], t[7], t[8]);
    else if(t[4]) time = new Date(t[2], t[3]-1, t[4]);
    else return 0;
  }
  return Math.round((time||new Date()).getTime()/1000)+(tzone||8)*3600;
}

上述函数支持以下四种格式的参数:

timestamp(); //当前时间戳
timestamp('1970-01-01'); //表示当日0点
timestamp('1970-01-01 00:00:01'); //日期以-分割
timestamp('1970/01/01 00:00:01'); //日期以/分割