本章实例摘自JavaScript语言精髓(JavaScript:The Good Parts)
一个匹配URl表达式的例子:
<script>
var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url = "http://www.ora.com:80/goodparts?q#fragment";
var result = parse_url.exec(url);
var names = ['url','scheme','slash','host','port','path','query','hash'];
var blanks = ' ';
var i;
for(i = 0;i<names.length;i++)
{
document.writeln(names[i]+':'+blanks.substring(names[i].length),result[i]+'</br >');
}
</script>
/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/
让我们看看parsr_url的各个因子是如何工作的
^
^
代表这个字符串的开始。它是一个标记,用来防止exec跳过不像URL的前缀。
(?:([A-Za-z]+):)?
这个因子匹配一个协议名,但仅当它后面跟随一个:时候才匹配(?: ...)表示一个非捕获型分组。后缀?表示 这个分组是可选的。它表示重复0次或者1次。(...)表示一个捕获性分组。一个捕获型分组将复制它所匹配的文本并将其放入result数组中。每个捕获型分组将被指定一个编号。第一个捕获型的分组编号是1,所以该分组所匹配的文本拷贝到result[1] 中。[...]表示一个字符类,这个字符类A-Za-z包含26个大写字母和26个小写字母,连缀字符(-)表示范围A-Z,后缀(+)表示可以匹配1次或者多次。这个数组后面跟着字符:,它将按字面匹配。
(\/{0,3})
最后的这个可选分组是以#开始的。.将匹配除了结束符以外的所有字符。
下一个因子的捕获分组2.\/表示一个应该被匹配的/(斜杠)。它用\(反斜杠)来进行转义,这样他就不会错误的解释这个正则表达式的结束符。 后缀{0,3}表示/将会被匹配0次或者1到3次之间:
下一个因子的捕获分组4,它由一个前置:加上一个或者多个数字为组成的序列。\d表示一个数字字符。一个或者多个数字组成的数字串将捕获型分组4捕获:
([0-9.\-A-Za-z]+)
下一个因子的捕获分组3.它将匹配一个主机名,由一个或者多个数字,字母或.或-组成。-将被转义为\-以防止与表示范围的连字符混淆:
(?::(\d+))?
(?:\/([^?#]*))?
第5个可选分组是以一个/开始。之后的字符类[^?#]以一个^开始,它表示这个类包含除了?和#之外所有的字符。*表示字符类将被匹配0次或者多次。注意在此是不严谨的。这个类匹配除?和#之外的所有字符,其中包含了行结束符,控制字符,以及其它的大量不应该被匹配的字符。大多数情况下,它会按照我们所说的去做,但是某些不好的文本会有漏进来的风险。不严谨的正则表达式是一个常见的安全漏洞发源地。写不严谨的比写严谨的要简单的多。
接下来还有一个以?开始的可选分组(第6个),这个分组包含0个或者多个非#字符:
(?:\?([^#]*))?
(?:#(.*))?
$
表示这个字符串的结束。他让我们确信这个份URl的尾部没有其它更多的内容。
一个匹配数字正则表达式的例子:
<script>
var parse_num = /^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i;
var test = function (num){
document.write(parse_num.test(num)+'</br>');
};
test("1");
test("number");
test("96.8");
test("132.21.86.100");
test("123.45E-67");
test("1234.5D-67");
</script>
/^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i
/^
$/i
我们用^和$来框定这个正则表达式,它将导致文本中的所有字符都要针对这个表达式进行匹配。如果省略了这些标识,那么只要一个字符串包含一个数字,这个正则表达式就会告诉我们,它是一个以*开头,以*结尾。
i标识规定匹配字母时忽略大小写。我们的模式中唯一可能出现的字母时E,我们希望e也可能匹配E,我们可以将e因子写成[eE]或者(?:E|e),但是不必这么麻烦,因为我们使用了标识符i;
-?-号后面的?后缀标示-是可选的:
\d+
\d匹配一个数字,其含义跟[0-9]一样,+标示它可以匹配1个或者多个数字;
(?:\.\d*)?( ?:... )表示一个可选的非捕获型分组,
i标识规定匹配字母时忽略大小写。我们的模式中唯一可能出现的字母时E,我们希望e也可能匹配E,我们可以将e因子写成[eE]或者(?:E|e),但是不必这么麻烦,因为我们使用了标识符i;
-?-号后面的?后缀标示-是可选的:
\d+
\d匹配一个数字,其含义跟[0-9]一样,+标示它可以匹配1个或者多个数字;
(?:\.\d*)?( ?:... )表示一个可选的非捕获型分组,
通常非捕获型分组来替代少量的不优美的捕获型分组是很好的方法,因为捕获型会有性能上的损失。这个分组将匹配后面跟随0个或者多个数字的小数点。
(?:e[+\-]?\d+)? 它将匹配一个e(E)一个可选的正负号以及一个或者多个数字。
(?:e[+\-]?\d+)? 它将匹配一个e(E)一个可选的正负号以及一个或者多个数字。
先写到这里,以后会慢慢补充